def definePlots(self, tree, noSel, sample=None, sampleCfg=None): from bamboo.plots import Plot from bamboo.plots import EquidistantBinning as EqBin from bamboo import treefunctions as op plots = [] el10 = op.select(tree.Electron, lambda el: el.pt > 10.) mu10 = op.select(tree.Muon, lambda mu: mu.pt > 10.) cleanedJets30 = op.select( tree.Jet, lambda j: op.AND( j.pt > 30., op.NOT( op.rng_any(el10, lambda el: op.deltaR(j.p4, el.p4) < 0.4)), op.NOT( op.rng_any(mu10, lambda mu: op.deltaR(j.p4, mu.p4) < 0.4))) ) plots.append( Plot.make1D("sumCleanedJetPt", op.rng_sum(cleanedJets30, lambda j: j.pt), noSel, EqBin(100, 15., 200.), title="Sum p_{T} (GeV/c)")) return plots
def makeFatjetMatch(gen1, gen2, recoFatJet): return op.combine( (gen1, gen2, recoFatJet), pred=lambda g1, g2, fat: op.AND( fat.subJet1.idx == op.rng_min_element_by( reco_subJet1_b_matched, lambda sub1_matched: op.deltaR( g1.p4, sub1_matched.p4)).idx, fat.subJet2.idx == op .rng_min_element_by( reco_subJet2_b_matched, lambda sub2_matched: op.deltaR( g2.p4, sub2_matched.p4)).idx))
def evaluateJPA_1b2Wj(lepton, muons, electrons, ak4jets, jets, bJetsL, bJetsM, met, model, HLL): #invars = [op.c_float(0.)]*12 invars = [bJetCorrPT(jets[0]), # bjet1_ptReg jets[0].btagDeepFlavB, # bjet1_btagCSV bJetCorrPT(jets[1]), # wjet1_ptReg jets[1].btagDeepFlavB, # wjet1_btagCSV jets[2].btagDeepFlavB, # wjet2_btagCSV jets[2].qgl, # wjet2_qgDiscr HLL.Wjj_simple(jets[1].p4, jets[2].p4).M(), # HadW_mass op.deltaR(HLL.Wjj_simple(jets[1].p4, jets[2].p4), lepton.p4), # dR_HadW_lep op.deltaR(jets[1].p4, jets[2].p4), # dR_wjet1wjet2 (HLL.bJetCorrP4(jets[0]) + HLL.Wjj_simple(jets[1].p4, jets[2].p4)).M(), # mTop1 = (WhadP4 + bJet1P4).M() op.rng_len(ak4jets), # nJets op.rng_len(bJetsM) # nBJetMedium ] return model(*invars, defineOnFirstUse=False)[0]
def evaluateJPA_Hbb2Wj(lepton, muons, electrons, fatJets, jets, bJetsL, bJetsM, met, model, HLL): #invars = [op.c_float(0.)]*14 invars = [jets[0].btagDeepB, # wjet1_btagCSV jets[0].qgl, # wjet1_qgDiscr jets[1].btagDeepB, # wjet2_btagCSV jets[1].qgl, # wjet2_qgDiscr (fatJets[0].subJet1.p4 + fatJets[0].subJet2.p4).Pt(), # Hbb_Pt HLL.Wjj_simple(jets[0].p4, jets[1].p4).M(), # HadW_mass #HLL.comp_cosThetaS(jets[0].p4, jets[1].p4), # HadW_cosTheta op.extMethod("HHbbWWJPA::cosThetaS", returnType="float")(jets[0].p4, jets[1].p4), #op.c_float(random.choice([0,1])), op.deltaR(HLL.Wjj_simple(jets[0].p4, jets[1].p4), lepton.p4), # dR_HadW_lep op.min(HLL.dR_HadW_bjet(fatJets[0].subJet1.p4, jets[0].p4, jets[1].p4), # min_dR_HadW_bjet HLL.dR_HadW_bjet(fatJets[0].subJet2.p4, jets[0].p4, jets[1].p4)), op.deltaR(jets[0].p4, jets[1].p4), # dR_wjet1wjet2 #HLL.HWW_simple(jets[0].p4, jets[1].p4, lepton.p4, met).M() # Hww_mass #(jets[0].p4+jets[1].p4+lepton.p4+met.p4).M() # Hww_mass op.extMethod("HHbbWWJPA::HWW_SimpleMassWithRecoNeutrino", returnType="float")(jets[0].p4, jets[1].p4, lepton.p4, met.p4) ] return model(*invars, defineOnFirstUse=False)[0]
def evaluateJPA_Hbb1Wj(lepton, muons, electrons, fatJets, jets, bJetsL, bJetsM, met, model, HLL): #invars = [op.c_float(0.)]*14 invars = [op.switch(fatJets[0].subJet1.btagDeepB > fatJets[0].subJet2.btagDeepB, # dEta_bjet1_lep op.abs(lepton.eta-fatJets[0].subJet1.eta), op.abs(lepton.eta-fatJets[0].subJet2.eta)), bJetCorrPT(jets[0]), # wjet1_ptReg jets[0].btagDeepB, # wjet1_btagCSV jets[0].qgl, # wjet1_qgDiscr op.deltaR(lepton.p4, jets[0].p4), # dR_wjet1_lep (fatJets[0].subJet1.p4 + fatJets[0].subJet2.p4).Pt(), # Hbb_Pt op.rng_len(bJetsM) # nBJetMedium ] return model(*invars, defineOnFirstUse=False)[0]
def makeResolvedJetPlots(self, sel, jets, uname): maxJet = 2 binScaling = 1 plots = [] for i in range(maxJet): plots.append( Plot.make1D(f"{uname}_jet{i+1}_pt", jets[i].pt, sel, EqB(60 // binScaling, 30., 730. - max(4, i) * 100), title=f"{utils.getCounter(i+1)} jet p_{{T}} [GeV]", plotopts=utils.getOpts(uname))) plots.append( Plot.make1D(f"{uname}_jet{i+1}_eta", jets[i].eta, sel, EqB(50 // binScaling, -2.4, 2.4), title=f"{utils.getCounter(i+1)} jet eta", plotopts=utils.getOpts(uname, **{"log-y": False}))) plots.append( Plot.make1D(f"{uname}_jet{i+1}_phi", jets[i].phi, sel, EqB(50 // binScaling, -3.1416, 3.1416), title=f"{utils.getCounter(i+1)} jet phi", plotopts=utils.getOpts(uname, **{"log-y": False}))) plots.append( Plot.make1D(f"{uname}_jet_DR", op.deltaR(jets[0].p4, jets[1].p4), sel, EqB(50, 0.3, 3.), title="Jets DR", plotopts=utils.getOpts(uname, **{"log-y": False}))) plots.append( Plot.make1D(f"{uname}_jet_M", op.invariant_mass(jets[0].p4, jets[1].p4), sel, EqB(60, 0., 400.), title="dijets invariant mass [GeV]", plotopts=utils.getOpts(uname))) plots.append( Plot.make1D(f"{uname}_jet_pT", (jets[0].p4 + jets[1].p4).Pt(), sel, EqB(60, 0., 600.), title=" dijets p_{T} [GeV]", plotopts=utils.getOpts(uname))) return plots
def evaluateJPA_2b1Wj(lepton, muons, electrons, ak4jets, jets, bJetsL, bJetsM, met, model, HLL): #invars = [op.c_float(0.)]*13 invars = [jets[0].btagDeepFlavB, # bjet1_btagCSV bJetCorrPT(jets[1]), # bjet2_ptReg jets[1].btagDeepFlavB, # bjet2_btagCSV jets[1].qgl, # bjet2_qgDiscr op.abs(lepton.eta - jets[1].eta), # dEta_bjet2_lep bJetCorrPT(jets[2]), # wjet1_ptReg jets[2].btagDeepFlavB, # wjet1_btagCSV jets[2].qgl, # wjet1_qgDiscr op.abs(lepton.eta - jets[2].eta), # dEta_wjet1_lep op.deltaR(jets[0].p4, jets[1].p4), # dR_bjet1bjet2 op.rng_len(ak4jets), # nJets op.rng_len(bJetsL), # nBJetLoose op.rng_len(bJetsM) # nBJetMedium ] return model(*invars, defineOnFirstUse=False)[0]
def makedeltaRPlots(sel, jets, leptons, suffix, uname): plots = [] plots.append( Plot.make1D(f"{uname}_{suffix}_jet1jet2_deltaR", op.deltaR(jets[0].p4, jets[1].p4), sel, EqBin(50, 0., 8.), title="#Delta R (leading jet, sub-leading jet)", plotopts=utils.getOpts(uname, **{"log-y": False}))) plots.append( Plot.make1D(f"{uname}_{suffix}_jet1lep1_deltaR", op.deltaR(jets[0].p4, leptons[0].p4), sel, EqBin(50, 0., 8.), title="#Delta R (leading jet, leading lepton)", plotopts=utils.getOpts(uname, **{"log-y": False}))) plots.append( Plot.make1D(f"{uname}_{suffix}_jet1lep2_deltaR", op.deltaR(jets[0].p4, leptons[1].p4), sel, EqBin(50, 0., 8.), title="#Delta R (leading jet, sub-leading lepton)", plotopts=utils.getOpts(uname, **{"log-y": False}))) plots.append( Plot.make1D(f"{uname}_{suffix}_jet2lep1_deltaR", op.deltaR(jets[1].p4, leptons[0].p4), sel, EqBin(50, 0., 8.), title="#Delta R (sub-leading jet, leading lepton)", plotopts=utils.getOpts(uname, **{"log-y": False}))) plots.append( Plot.make1D(f"{uname}_{suffix}_jet2lep2_deltaR", op.deltaR(jets[1].p4, leptons[1].p4), sel, EqBin(50, 0., 8.), title="#Delta R (leading jet, sub-leading lepton)", plotopts=utils.getOpts(uname, **{"log-y": False}))) plots.append( Plot.make1D(f"{uname}_{suffix}_lep1lep2_deltaR", op.deltaR(leptons[0].p4, leptons[1].p4), sel, EqBin(50, 0., 8.), title="#Delta R (leading lepton, sub-leading lepton)", plotopts=utils.getOpts(uname, **{"log-y": False}))) return plots
def makehistosforTTbarEstimation(selections, ll, bjets, wp, met, suffix, uname): plots = [] for key, sel in selections.items(): tagger = key.replace(wp, "") bjets_ = safeget(bjets, tagger, wp) bb = bjets[key.replace(wp, "")][wp] plots += [ Plot.make1D( f"{nm}_{uname}_{suffix}_jets_{tagger}_btag{wp}_mll_and_{met}", llbbVar, sel, binning, title=title, plotopts=utils.getOpts(uname)) for nm, (llbbVar, binning, title) in { "jj_M": (op.invariant_mass(bb[0].p4 + bb[1].p4), EqBin(40, 10., 1000.), "Mjj [GeV]"), "lljj_M": ((ll[0].p4 + ll[1].p4 + bb[0].p4 + bb[1].p4).M(), EqBin(50, 100., 1500.), "Mlljj [GeV]"), "ll_M": (op.invariant_mass(ll[0].p4 + ll[1].p4), EqBin(60, 70., 120.), "Mll [GeV]"), "jj_DR": (op.deltaR(bb[0].p4, bb[1].p4), EqBin(50, 0., 6.), "jj deltaR"), "jj_pt": ((bjets_[0].p4 + bjets_[1].p4).Pt(), EqBin(50, 0., 450.), "dijets p_{T} [GeV]"), "jet1_pt": (bb[0].pt, EqBin(50, 20., 500.), "jet1 p_{T} [GeV]"), "jet2_pt": (bb[1].pt, EqBin(50, 20., 300.), "jet2 p_{T} [GeV]"), "lep1_pt": (ll[0].pt, EqBin(50, 20., 400.), "Leading Lepton p_{T} [GeV]"), "lep2_pt": (ll[1].pt, EqBin(50, 10., 200.), "Sub-leading Lepton p_{T} [GeV]"), }.items() ] return plots
def definePlots(self, t, noSel, sample=None, sampleCfg=None): noSel = super(TransferFunction, self).prepareObjects(t, noSel, sample, sampleCfg, 'DL') noSel = self.beforeJetselection(noSel) era = sampleCfg['era'] plots = [] if not self.is_MC: return plots lambda_is_matched = lambda lep: op.OR( lep.genPartFlav == 1, # Prompt muon or electron lep.genPartFlav == 15) # From tau decay #lep.genPartFlav==22) # From photon conversion (only available for electrons) plots.append( Plot.make1D("totalWeight", noSel.weight, noSel, EquidistantBinning(100, -int(10**5), int(10**5)), xTitle="total weight")) plots.append( Plot.make1D("genWeight", t.genWeight, noSel, EquidistantBinning(100, -int(10**5), int(10**5)), xTitle="gen weight")) ########################################################## # Leptons # ########################################################## #----- Gen particles -----# gen_e = op.select( t.GenPart, lambda g: op.AND( op.abs(g.pdgId) == 11, g.statusFlags & (0x1 << 13), g.pt >= 10, op.abs(g.eta) < 2.5)) gen_m = op.select( t.GenPart, lambda g: op.AND( op.abs(g.pdgId) == 13, g.statusFlags & (0x1 << 13), g.pt >= 10, op.abs(g.eta) < 2.4)) #----- Reco particles -----# lambda_reco_e = lambda el: op.AND( op.abs(el.pdgId) == 11, el.pt >= 10, op.abs(el.eta) < 2.5, lambda_is_matched(el)) lambda_reco_m = lambda mu: op.AND( op.abs(mu.pdgId) == 13, mu.pt >= 10, op.abs(mu.eta) < 2.4, lambda_is_matched(mu)) reco_e = op.select(self.electronsFakeSel, lambda_reco_e) reco_m = op.select(self.muonsFakeSel, lambda_reco_m) #---- Matching -----# lambda_lepton_match = lambda gen, reco: op.AND( op.deltaR(gen.p4, reco.p4) < 0.1, (op.abs(gen.pt - reco.pt) / (gen.pt + reco.pt)) < 0.2) # reco_e_matched = op.select(reco_e, lambda re : op.rng_any(gen_e, lambda ge: lambda_lepton_match(ge,re))) # reco_m_matched = op.select(reco_m, lambda rm : op.rng_any(gen_m, lambda gm: lambda_lepton_match(gm,rm))) #match_e = op.combine((gen_e,reco_e), pred = lambda ge,re : re.idx == op.rng_min_element_by(reco_e_matched,lambda re_matched : op.deltaR(ge.p4,re_matched.p4)).idx) #match_m = op.combine((gen_m,reco_m), pred = lambda gm,rm : rm.idx == op.rng_min_element_by(reco_m_matched,lambda rm_matched : op.deltaR(gm.p4,rm_matched.p4)).idx) match_e = op.combine((gen_e, reco_e), pred=lambda_lepton_match) match_m = op.combine((gen_m, reco_m), pred=lambda_lepton_match) plots.extend(plotMatching("e", match_e, noSel, "e^{#pm}")) plots.extend(plotMatching("m", match_m, noSel, "#mu^{#pm}")) # plots.append(plotRecoForGen(noSel,gen_e,tight_e,lambda_lepton_match,"e_tight")) # plots.append(plotRecoForGen(noSel,gen_e,tight_m,lambda_lepton_match,"m_tight")) ########################################################## # Ak4 B jets # ########################################################## #----- RecoJets -----# recoJet_b = op.select( t.Jet, lambda j: op.AND( op.abs(j.partonFlavour) == 5, j.pt >= 20, op.abs(j.eta) < 2.4, j.genJet.isValid)) #----- Parton -----# gen_b = op.select( t.GenPart, lambda g: op.AND( op.abs(g.pdgId) == 5, g.statusFlags & (0x1 << 13), g.pt >= 20, op.abs(g.eta) < 2.4)) #----- Matching -----# lambda_jet_match = lambda gen, reco: op.AND( op.deltaR(gen.p4, reco.p4) < 0.2) reco_b_matched = op.select( recoJet_b, lambda jetb: op.rng_any( gen_b, lambda gb: lambda_jet_match(gb, jetb))) match_b = op.combine( (gen_b, recoJet_b), pred=lambda gb, jetb: jetb.idx == op.rng_min_element_by( reco_b_matched, lambda rb_matched: op.deltaR( gb.p4, rb_matched.p4)).idx) plots.extend(plotMatching("ak4b", match_b, noSel, "b")) ########################################################## # Ak4 C jets # ########################################################## #----- RecoJets -----# recoJet_c = op.select( t.Jet, lambda j: op.AND( op.abs(j.partonFlavour) == 4, j.pt >= 20, op.abs(j.eta) < 2.4, j.genJet.isValid)) #----- Parton -----# gen_c = op.select( t.GenPart, lambda g: op.AND( op.abs(g.pdgId) == 4, g.statusFlags & (0x1 << 13), g.pt >= 20, op.abs(g.eta) < 2.4)) #----- Matching -----# reco_c_matched = op.select( recoJet_c, lambda jetc: op.rng_any( gen_c, lambda gc: lambda_jet_match(gc, jetc))) match_c = op.combine( (gen_c, recoJet_c), pred=lambda gc, jetc: jetc.idx == op.rng_min_element_by( reco_c_matched, lambda rc_matched: op.deltaR( gc.p4, rc_matched.p4)).idx) plots.extend(plotMatching("ak4c", match_c, noSel, "c")) ########################################################## # Ak4 lightjets # ########################################################## #----- RecoJets -----# recoJet_l = op.select( t.Jet, lambda j: op.AND( op.OR( op.abs(j.partonFlavour) == 1, op.abs(j.partonFlavour) == 2, op.abs(j.partonFlavour) == 3), j.pt >= 20, op.abs(j.eta) < 2.4, j.genJet.isValid)) #----- Parton -----# gen_l = op.select( t.GenPart, lambda g: op.AND( op.OR( op.abs(g.pdgId) == 1, op.abs(g.pdgId) == 2, op.abs(g.pdgId) == 3), g.statusFlags & (0x1 << 13), g.pt >= 20, op.abs(g.eta) < 2.4)) #----- Matching -----# reco_l_matched = op.select( recoJet_l, lambda jetl: op.rng_any( gen_l, lambda gl: lambda_jet_match(gl, jetl))) match_l = op.combine( (gen_l, recoJet_l), pred=lambda gl, jetl: jetl.idx == op.rng_min_element_by( reco_l_matched, lambda rl_matched: op.deltaR( gl.p4, rl_matched.p4)).idx) plots.extend(plotMatching("ak4l", match_l, noSel, "l")) ########################################################## # Ak8 jets # ########################################################## #----- RecoJets -----# recoFatJet = op.select( t.FatJet, lambda j: op.AND( j.pt >= 100, op.abs(j.eta) < 2.4, op.AND(j.subJet1.isValid, j.subJet1.pt >= 20., op.abs(j.subJet1.eta) <= 2.4, j.subJet2.isValid, j. subJet2.pt >= 20., op.abs(j.subJet2.eta) <= 2.4), op.AND(j.msoftdrop >= 30, j.msoftdrop <= 210), j.tau2 / j.tau1 <= 0.75)) #plots.extend(fatjetPlots(noSel,recoFatJet,"fatjet")) reco_subJet1_b_matched = op.select( recoFatJet, lambda fat: op.rng_any( gen_b, lambda gb: lambda_jet_match(gb, fat.subJet1))) reco_subJet2_b_matched = op.select( recoFatJet, lambda fat: op.rng_any( gen_b, lambda gb: lambda_jet_match(gb, fat.subJet2))) reco_subJet1_c_matched = op.select( recoFatJet, lambda fat: op.rng_any( gen_c, lambda gc: lambda_jet_match(gc, fat.subJet1))) reco_subJet2_c_matched = op.select( recoFatJet, lambda fat: op.rng_any( gen_c, lambda gc: lambda_jet_match(gc, fat.subJet2))) reco_subJet1_l_matched = op.select( recoFatJet, lambda fat: op.rng_any( gen_l, lambda gl: lambda_jet_match(gl, fat.subJet1))) reco_subJet2_l_matched = op.select( recoFatJet, lambda fat: op.rng_any( gen_l, lambda gl: lambda_jet_match(gl, fat.subJet2))) def makeFatjetMatch(gen1, gen2, recoFatJet): return op.combine( (gen1, gen2, recoFatJet), pred=lambda g1, g2, fat: op.AND( fat.subJet1.idx == op.rng_min_element_by( reco_subJet1_b_matched, lambda sub1_matched: op.deltaR( g1.p4, sub1_matched.p4)).idx, fat.subJet2.idx == op .rng_min_element_by( reco_subJet2_b_matched, lambda sub2_matched: op.deltaR( g2.p4, sub2_matched.p4)).idx)) match_fat_bb = makeFatjetMatch(gen_b, gen_b, recoFatJet) match_fat_bc = makeFatjetMatch(gen_b, gen_c, recoFatJet) match_fat_bl = makeFatjetMatch(gen_b, gen_l, recoFatJet) match_fat_cb = makeFatjetMatch(gen_c, gen_b, recoFatJet) match_fat_cc = makeFatjetMatch(gen_c, gen_c, recoFatJet) match_fat_cl = makeFatjetMatch(gen_c, gen_l, recoFatJet) match_fat_lb = makeFatjetMatch(gen_l, gen_b, recoFatJet) match_fat_lc = makeFatjetMatch(gen_l, gen_c, recoFatJet) match_fat_ll = makeFatjetMatch(gen_l, gen_l, recoFatJet) # match_fat_bb = op.combine((gen_b,gen_b,recoFatJet), pred = lambda g1,g2,fat : op.AND( # fat.subJet1.idx == op.rng_min_element_by(reco_subJet1_b_matched, # lambda sub1_matched : op.deltaR(gb1.p4,sub1_matched.p4)).idx, # fat.subJet2.idx == op.rng_min_element_by(reco_subJet2_b_matched, # lambda sub2_matched : op.deltaR(gb2.p4,sub2_matched.p4)).idx)) # match_fat_bc = op.combine((gen_b,gen_b,recoFatJet), pred = lambda gb1,gb2,fat : op.AND( # fat.subJet1.idx == op.rng_min_element_by(reco_subJet1_b_matched, # lambda sub1_matched : op.deltaR(gb1.p4,sub1_matched.p4)).idx, # fat.subJet2.idx == op.rng_min_element_by(reco_subJet2_b_matched, # lambda sub2_matched : op.deltaR(gb2.p4,sub2_matched.p4)).idx)) plots.extend(plotFatjetMatching(match_fat_bb, noSel, 'b', 'b')) plots.extend(plotFatjetMatching(match_fat_bc, noSel, 'b', 'c')) plots.extend(plotFatjetMatching(match_fat_bl, noSel, 'b', 'l')) plots.extend(plotFatjetMatching(match_fat_cb, noSel, 'c', 'b')) plots.extend(plotFatjetMatching(match_fat_cc, noSel, 'c', 'c')) plots.extend(plotFatjetMatching(match_fat_cl, noSel, 'c', 'l')) plots.extend(plotFatjetMatching(match_fat_bb, noSel, 'l', 'b')) plots.extend(plotFatjetMatching(match_fat_bc, noSel, 'l', 'c')) plots.extend(plotFatjetMatching(match_fat_bl, noSel, 'l', 'l')) return plots
def definePlots(self, t, noSel, sample=None, sampleCfg=None): # Some imports # from bamboo.analysisutils import forceDefine era = sampleCfg['era'] # Get pile-up configs # puWeightsFile = None if era == "2016": sfTag = "94X" puWeightsFile = os.path.join(os.path.dirname(__file__), "data", "puweights2016.json") elif era == "2017": sfTag = "94X" puWeightsFile = os.path.join(os.path.dirname(__file__), "data", "puweights2017.json") elif era == "2018": sfTag = "102X" puWeightsFile = os.path.join(os.path.dirname(__file__), "data", "puweights2018.json") if self.isMC(sample) and puWeightsFile is not None: from bamboo.analysisutils import makePileupWeight noSel = noSel.refine("puWeight", weight=makePileupWeight(puWeightsFile, t.Pileup_nTrueInt, systName="pileup")) isMC = self.isMC(sample) plots = [] forceDefine(t._Muon.calcProd, noSel) ############################################################################# ################################ Muons ##################################### ############################################################################# # Wp // 2016- 2017 -2018 : Muon_mediumId // https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideMuonIdRun2#Muon_Isolation muonsByPt = op.sort(t.Muon, lambda mu: -mu.p4.Pt()) muons = op.select( muonsByPt, lambda mu: op.AND(mu.p4.Pt() > 10., op.abs(mu.p4.Eta()) < 2.4, mu.tightId, mu.pfRelIso04_all < 0.15)) # Scalefactors # #if era=="2016": # doubleMuTrigSF = get_scalefactor("dilepton", ("doubleMuLeg_HHMoriond17_2016"), systName="mumutrig") # muMediumIDSF = get_scalefactor("lepton", ("muon_{0}_{1}".format(era, sfTag), "id_medium"), combine="weight", systName="muid") # muMediumISOSF = get_scalefactor("lepton", ("muon_{0}_{1}".format(era, sfTag), "iso_tight_id_medium"), combine="weight", systName="muiso") # TrkIDSF = get_scalefactor("lepton", ("muon_{0}_{1}".format(era, sfTag), "highpt"), combine="weight") # TrkISOSF = get_scalefactor("lepton", ("muon_{0}_{1}".format(era, sfTag), "isotrk_loose_idtrk_tightidandipcut"), combine="weight") #else: # muMediumIDSF = get_scalefactor("lepton", ("muon_{0}_{1}".format(era, sfTag), "id_medium"), systName="muid") # muMediumISOSF = get_scalefactor("lepton", ("muon_{0}_{1}".format(era, sfTag), "iso_tight_id_medium"), systName="muiso") ############################################################################# ############################# Electrons ################################### ############################################################################# #Wp // 2016: Electron_cutBased_Sum16==3 -> medium // 2017 -2018 : Electron_cutBased ==3 --> medium ( Fall17_V2) # asking for electrons to be in the Barrel region with dz<1mm & dxy< 0.5mm // Endcap region dz<2mm & dxy< 0.5mm electronsByPt = op.sort(t.Electron, lambda ele: -ele.p4.Pt()) electrons = op.select( electronsByPt, lambda ele: op.AND(ele.p4.Pt() > 15., op.abs(ele.p4.Eta()) < 2.5, ele.cutBased >= 3) ) # //cut-based ID Fall17 V2 the recomended one from POG for the FullRunII # Scalefactors # #elMediumIDSF = get_scalefactor("lepton", ("electron_{0}_{1}".format(era,sfTag), "id_medium"), systName="elid") #doubleEleTrigSF = get_scalefactor("dilepton", ("doubleEleLeg_HHMoriond17_2016"), systName="eleltrig") #elemuTrigSF = get_scalefactor("dilepton", ("elemuLeg_HHMoriond17_2016"), systName="elmutrig") #mueleTrigSF = get_scalefactor("dilepton", ("mueleLeg_HHMoriond17_2016"), systName="mueltrig") OsElEl = op.combine( electrons, N=2, pred=lambda el1, el2: op.AND(el1.charge != el2.charge, el1.p4.Pt() > 25, el2.p4.Pt() > 15)) OsMuMu = op.combine( muons, N=2, pred=lambda mu1, mu2: op.AND(mu1.charge != mu2.charge, mu1.p4.Pt() > 25, mu2.p4.Pt() > 15)) OsElMu = op.combine((electrons, muons), pred=lambda el, mu: op.AND(el.charge != mu.charge, el.p4.Pt() > 25, mu.p4.Pt() > 15)) OsMuEl = op.combine((electrons, muons), pred=lambda el, mu: op.AND(el.charge != mu.charge, el.p4.Pt() > 15, mu.p4.Pt() > 25)) hasOsElEl = noSel.refine("hasOsElEl", cut=[op.rng_len(OsElEl) >= 1]) hasOsMuMu = noSel.refine("hasOsMuMu", cut=[op.rng_len(OsMuMu) >= 1]) hasOsElMu = noSel.refine("hasOsElMu", cut=[op.rng_len(OsElMu) >= 1]) hasOsMuEl = noSel.refine("hasOsMuEl", cut=[op.rng_len(OsMuEl) >= 1]) plots.append( Plot.make1D("ElEl_channel", op.rng_len(OsElEl), noSel, EquidistantBinning(10, 0, 10.), title='Number of dilepton events in ElEl channel', xTitle='N_{dilepton} (ElEl channel)')) plots.append( Plot.make1D("MuMu_channel", op.rng_len(OsMuMu), noSel, EquidistantBinning(10, 0, 10.), title='Number of dilepton events in MuMu channel', xTitle='N_{dilepton} (MuMu channel)')) plots.append( Plot.make1D("ElMu_channel", op.rng_len(OsElMu), noSel, EquidistantBinning(10, 0, 10.), title='Number of dilepton events in ElMu channel', xTitle='N_{dilepton} (ElMu channel)')) plots.append( Plot.make1D("MuEl_channel", op.rng_len(OsMuEl), noSel, EquidistantBinning(10, 0, 10.), title='Number of dilepton events in MuEl channel', xTitle='N_{dilepton} (MuEl channel)')) plots += makeDileptonPlots(self, sel=hasOsElEl, dilepton=OsElEl[0], suffix='hasOsdilep', channel='ElEl') plots += makeDileptonPlots(self, sel=hasOsMuMu, dilepton=OsMuMu[0], suffix='hasOsdilep', channel='MuMu') plots += makeDileptonPlots(self, sel=hasOsElMu, dilepton=OsElMu[0], suffix='hasOsdilep', channel='ElMu') plots += makeDileptonPlots(self, sel=hasOsMuEl, dilepton=OsMuEl[0], suffix='hasOsdilep', channel='MuEl') # Dilepton Z peak exclusion (charge already done in previous selection) # lambda_mllLowerband = lambda dilep: op.in_range( 12., op.invariant_mass(dilep[0].p4, dilep[1].p4), 80.) lambda_mllUpperband = lambda dilep: op.invariant_mass( dilep[0].p4, dilep[1].p4) > 100. lambda_mllCut = lambda dilep: op.OR(lambda_mllLowerband(dilep), lambda_mllUpperband(dilep)) hasOsElElOutZ = hasOsElEl.refine("hasOsElElOutZ", cut=[lambda_mllCut(OsElEl[0])]) hasOsMuMuOutZ = hasOsMuMu.refine("hasOsMuMuOutZ", cut=[lambda_mllCut(OsMuMu[0])]) hasOsElMuOutZ = hasOsElMu.refine("hasOsElMuOutZ", cut=[lambda_mllCut(OsElMu[0])]) hasOsMuElOutZ = hasOsMuEl.refine("hasOsMuElOutZ", cut=[lambda_mllCut(OsMuEl[0])]) plots += makeDileptonPlots(self, sel=hasOsElElOutZ, dilepton=OsElEl[0], suffix='hasOsdilep_OutZ', channel='ElEl') plots += makeDileptonPlots(self, sel=hasOsMuMuOutZ, dilepton=OsMuMu[0], suffix='hasOsdilep_OutZ', channel='MuMu') plots += makeDileptonPlots(self, sel=hasOsElMuOutZ, dilepton=OsElMu[0], suffix='hasOsdilep_OutZ', channel='ElMu') plots += makeDileptonPlots(self, sel=hasOsMuElOutZ, dilepton=OsMuEl[0], suffix='hasOsdilep_OutZ', channel='MuEl') ############################################################################# ################################ Jets ##################################### ############################################################################# # select jets // 2016 - 2017 - 2018 ( j.jetId &2) -> tight jet ID jetsByPt = op.sort(t.Jet, lambda jet: -jet.p4.Pt()) jetsSel = op.select(jetsByPt, lambda j: op.AND(j.p4.Pt() > 20., op.abs(j.p4.Eta()) < 2.4, (j.jetId & 2))) # Jets = AK4 jets fatjetsByPt = op.sort(t.FatJet, lambda fatjet: -fatjet.p4.Pt()) fatjetsSel = op.select( fatjetsByPt, lambda j: op.AND(j.p4.Pt() > 20., op.abs(j.p4.Eta()) < 2.4, (j.jetId & 2))) # FatJets = AK8 jets # exclude from the jetsSel any jet that happens to include within its reconstruction cone a muon or an electron. jets = op.select( jetsSel, lambda j: op.AND( op.NOT( op.rng_any(electrons, lambda ele: op.deltaR(j.p4, ele.p4) < 0.3)), op.NOT( op.rng_any(muons, lambda mu: op.deltaR(j.p4, mu.p4) < 0.3)) )) fatjets = op.select( fatjetsSel, lambda j: op.AND( op.NOT( op.rng_any(electrons, lambda ele: op.deltaR(j.p4, ele.p4) < 0.3)), op.NOT( op.rng_any(muons, lambda mu: op.deltaR(j.p4, mu.p4) < 0.3)) )) # Boosted and resolved jets categories # if era == "2016": # Must check that subJet exists before looking at the btag lambda_boosted = lambda fatjet: op.OR( op.AND(fatjet.subJet1._idx.result != -1, fatjet.subJet1. btagDeepB > 0.6321), op.AND(fatjet.subJet2._idx.result != -1, fatjet.subJet2. btagDeepB > 0.6321)) lambda_resolved = lambda jet: jet.btagDeepB > 0.6321 elif era == "2017": lambda_boosted = lambda fatjet: op.OR( op.AND(fatjet.subJet1._idx.result != -1, fatjet.subJet1. btagDeepB > 0.4941), op.AND(fatjet.subJet2._idx.result != -1, fatjet.subJet2. btagDeepB > 0.4941)) lambda_resolved = lambda jet: jet.btagDeepB > 0.4941 elif era == "2018": lambda_boosted = lambda fatjet: op.OR( op.AND(fatjet.subJet1._idx.result != -1, fatjet.subJet1. btagDeepB > 0.4184), op.AND(fatjet.subJet2._idx.result != -1, fatjet.subJet2. btagDeepB > 0.4184)) lambda_resolved = lambda jet: jet.btagDeepB > 0.4184 # Select the bjets we want # bjetsResolved = op.select(jets, lambda_resolved) bjetsBoosted = op.select(fatjets, lambda_boosted) # Define the boosted and Resolved (+exclusive) selections # hasBoostedJets = noSel.refine("hasBoostedJets", cut=[op.rng_len(bjetsBoosted) >= 1]) hasNotBoostedJets = noSel.refine("hasNotBoostedJets", cut=[op.rng_len(bjetsBoosted) == 0]) hasResolvedJets = noSel.refine( "hasResolvedJets", cut=[op.rng_len(jets) >= 2, op.rng_len(bjetsResolved) >= 1]) hasNotResolvedJets = noSel.refine( "hasNotResolvedJets", cut=[op.OR(op.rng_len(jets) <= 1, op.rng_len(bjetsResolved) == 0)]) hasBoostedAndResolvedJets = noSel.refine( "hasBoostedAndResolvedJets", cut=[ op.rng_len(bjetsBoosted) >= 1, op.rng_len(jets) >= 2, op.rng_len(bjetsResolved) >= 1 ]) hasNotBoostedAndResolvedJets = noSel.refine( "hasNotBoostedAndResolvedJets", cut=[ op.OR( op.rng_len(bjetsBoosted) == 0, op.rng_len(jets) <= 1, op.rng_len(bjetsResolved) == 0) ]) hasExlusiveResolvedJets = noSel.refine( "hasExlusiveResolved", cut=[ op.rng_len(jets) >= 2, op.rng_len(bjetsResolved) >= 1, op.rng_len(bjetsBoosted) == 0 ]) hasNotExlusiveResolvedJets = noSel.refine( "hasNotExlusiveResolved", cut=[ op.OR( op.OR( op.rng_len(jets) <= 1, op.rng_len(bjetsResolved) == 0), op.AND( op.rng_len(bjetsBoosted) >= 1, op.rng_len(jets) >= 2, op.rng_len(bjetsResolved) >= 1)) ]) hasExlusiveBoostedJets = noSel.refine( "hasExlusiveBoostedJets", cut=[ op.rng_len(bjetsBoosted) >= 1, op.OR(op.rng_len(jets) <= 1, op.rng_len(bjetsResolved) == 0) ]) hasNotExlusiveBoostedJets = noSel.refine( "hasNotExlusiveBoostedJets", cut=[ op.OR( op.rng_len(bjetsBoosted) == 0, op.AND( op.rng_len(jets) >= 2, op.rng_len(bjetsResolved) >= 1)) ]) # Counting events from different selections for debugging # # Passing Boosted selection # PassedBoosted = Plot.make1D("PassedBoosted", op.c_int(1), hasBoostedJets, EquidistantBinning(2, 0., 2.), title='Passed Boosted', xTitle='Passed Boosted') FailedBoosted = Plot.make1D("FailedBoosted", op.c_int(0), hasNotBoostedJets, EquidistantBinning(2, 0., 2.), title='Failed Boosted', xTitle='Failed Boosted') plots.append( SummedPlot("BoostedCase", [FailedBoosted, PassedBoosted], xTitle="Boosted selection")) # Passing Resolved selection # PassedResolved = Plot.make1D("PassedResolved", op.c_int(1), hasResolvedJets, EquidistantBinning(2, 0., 2.), title='Passed Resolved', xTitle='Passed Resolved') FailedResolved = Plot.make1D("FailedResolved", op.c_int(0), hasNotResolvedJets, EquidistantBinning(2, 0., 2.), title='Failed Resolved', xTitle='Failed Resolved') plots.append( SummedPlot("ResolvedCase", [FailedResolved, PassedResolved], xTitle="Resolved selection")) # Passing Exclusive Resolved (Resolved AND NOT Boosted) # PassedExclusiveResolved = Plot.make1D( "PassedExclusiveResolved", op.c_int(1), hasExlusiveResolvedJets, EquidistantBinning(2, 0., 2.), title='Passed Exclusive Resolved', xTitle='Passed Exclusive Resolved') FailedExclusiveResolved = Plot.make1D( "FailedExclusiveResolved", op.c_int(0), hasNotExlusiveResolvedJets, EquidistantBinning(2, 0., 2.), title='Failed Exclusive Resolved', xTitle='Failed Exclusive Resolved') plots.append( SummedPlot("ExclusiveResolvedCase", [FailedExclusiveResolved, PassedExclusiveResolved], xTitle="Exclusive Resolved selection")) # Passing Exclusive Boosted (Boosted AND NOT Resolved) # PassedExclusiveBoosted = Plot.make1D("PassedExclusiveBoosted", op.c_int(1), hasExlusiveBoostedJets, EquidistantBinning(2, 0., 2.), title='Passed Exclusive Boosted', xTitle='Passed Exclusive Boosted') FailedExclusiveBoosted = Plot.make1D("FailedExclusiveBoosted", op.c_int(0), hasNotExlusiveBoostedJets, EquidistantBinning(2, 0., 2.), title='Failed Exclusive Boosted', xTitle='Failed Exclusive Boosted') plots.append( SummedPlot("ExclusiveBoostedCase", [FailedExclusiveBoosted, PassedExclusiveBoosted], xTitle="Exclusive Boosted selection")) # Passing Boosted AND Resolved # PassedBoth = Plot.make1D("PassedBoth", op.c_int(1), hasBoostedAndResolvedJets, EquidistantBinning(2, 0., 2.), title='Passed Both Boosted and Resolved', xTitle='Passed Boosted and Resolved') FailedBoth = Plot.make1D( "FailedBoth", # Means failed the (Boosted AND Resolved) = either one or the other op.c_int(0), hasNotBoostedAndResolvedJets, EquidistantBinning(2, 0., 2.), title='Failed combination Boosted and Resolved', xTitle='Failed combination') plots.append( SummedPlot("BoostedAndResolvedCase", [FailedBoth, PassedBoth], xTitle="Boosted and Resolved selection")) # Count number of boosted and resolved jets # plots.append( Plot.make1D("NBoostedJets", op.rng_len(bjetsBoosted), hasBoostedJets, EquidistantBinning(5, 0., 5.), title='Number of boosted jets in boosted case', xTitle='N boosted bjets')) plots.append( Plot.make1D( "NResolvedJets", op.rng_len(bjetsResolved), hasExlusiveResolvedJets, EquidistantBinning(5, 0., 5.), title='Number of resolved jets in exclusive resolved case', xTitle='N resolved bjets')) # Plot number of subjets in the boosted fatjets # lambda_noSubjet = lambda fatjet: op.AND( fatjet.subJet1._idx.result == -1, op.AND(fatjet.subJet2._idx.result == -1)) lambda_oneSubjet = lambda fatjet: op.AND( fatjet.subJet1._idx.result != -1, op.AND(fatjet.subJet2._idx.result == -1)) lambda_twoSubjet = lambda fatjet: op.AND( fatjet.subJet1._idx.result != -1, op.AND(fatjet.subJet2._idx.result != -1)) hasNoSubjet = hasBoostedJets.refine( "hasNoSubjet", cut=[lambda_noSubjet(bjetsBoosted[0])]) hasOneSubjet = hasBoostedJets.refine( "hasOneSubjet", cut=[lambda_oneSubjet(bjetsBoosted[0])]) hasTwoSubjet = hasBoostedJets.refine( "hasTwoSubjet", cut=[lambda_twoSubjet(bjetsBoosted[0])]) plot_hasNoSubjet = Plot.make1D( "plot_hasNoSubjet", # Fill bin 0 op.c_int(0), hasNoSubjet, EquidistantBinning(3, 0., 3.), title='Boosted jet without subjet') plot_hasOneSubjet = Plot.make1D( "plot_hasOneSubjet", # Fill bin 1 op.c_int(1), hasOneSubjet, EquidistantBinning(3, 0., 3.), title='Boosted jet with one subjet') plot_hasTwoSubjet = Plot.make1D( "plot_hasTwoSubjet", # Fill bin 2 op.c_int(2), hasTwoSubjet, EquidistantBinning(3, 0., 3.), title='Boosted jet with two subjets') plots.append( SummedPlot( "NumberOfSubjets", [plot_hasNoSubjet, plot_hasOneSubjet, plot_hasTwoSubjet], xTitle="Number of subjets in boosted jet")) # Plot jets quantities without the dilepton selections # plots += makeFatJetPlots(self, sel=hasBoostedJets, fatjet=bjetsBoosted[0], suffix="BoostedJets", channel="NoChannel") plots += makeJetsPlots(self, sel=hasResolvedJets, jets=bjetsResolved, suffix="ResolvedJets", channel="NoChannel") ############################################################################# ##################### Jets + Dilepton combination ########################### ############################################################################# # Combine dilepton and Resolved (Exclusive = NOT Boosted) selections # hasOsElElOutZResolvedJets = hasOsElElOutZ.refine( "hasOsElElOutZResolvedJets", cut=[ op.rng_len(jets) >= 2, op.rng_len(bjetsResolved) >= 1, op.rng_len(bjetsBoosted) == 0 ]) hasOsMuMuOutZResolvedJets = hasOsMuMuOutZ.refine( "hasOsMuMuOutZResolvedJets", cut=[ op.rng_len(jets) >= 2, op.rng_len(bjetsResolved) >= 1, op.rng_len(bjetsBoosted) == 0 ]) hasOsElMuOutZResolvedJets = hasOsElMuOutZ.refine( "hasOsElMuOutZResolvedJets", cut=[ op.rng_len(jets) >= 2, op.rng_len(bjetsResolved) >= 1, op.rng_len(bjetsBoosted) == 0 ]) hasOsMuElOutZResolvedJets = hasOsMuElOutZ.refine( "hasOsMuElOutZResolvedJets", cut=[ op.rng_len(jets) >= 2, op.rng_len(bjetsResolved) >= 1, op.rng_len(bjetsBoosted) == 0 ]) # Combine dilepton and Boosted selections # hasOsElElOutZBoostedJets = hasOsElElOutZ.refine( "hasOsElElOutZBoostedJets", cut=[op.rng_len(bjetsBoosted) >= 1]) hasOsMuMuOutZBoostedJets = hasOsMuMuOutZ.refine( "hasOsMuMuOutZBoostedJets", cut=[op.rng_len(bjetsBoosted) >= 1]) hasOsElMuOutZBoostedJets = hasOsElMuOutZ.refine( "hasOsElMuOutZBoostedJets", cut=[op.rng_len(bjetsBoosted) >= 1]) hasOsMuElOutZBoostedJets = hasOsMuElOutZ.refine( "hasOsMuElOutZBoostedJets", cut=[op.rng_len(bjetsBoosted) >= 1]) # Plot dilepton with OS, Z peak and Resolved jets selections # plots += makeDileptonPlots(self, sel=hasOsElElOutZResolvedJets, dilepton=OsElEl[0], suffix='hasOsdilep_OutZ_ResolvedJets', channel='ElEl') plots += makeDileptonPlots(self, sel=hasOsMuMuOutZResolvedJets, dilepton=OsMuMu[0], suffix='hasOsdilep_OutZ_ResolvedJets', channel='MuMu') plots += makeDileptonPlots(self, sel=hasOsElMuOutZResolvedJets, dilepton=OsElMu[0], suffix='hasOsdilep_OutZ_ResolvedJets', channel='ElMu') plots += makeDileptonPlots(self, sel=hasOsMuElOutZResolvedJets, dilepton=OsMuEl[0], suffix='hasOsdilep_OutZ_ResolvedJets', channel='MuEl') # Plot dilepton with OS dilepton, Z peak and Boosted jets selections # plots += makeDileptonPlots(self, sel=hasOsElElOutZBoostedJets, dilepton=OsElEl[0], suffix='hasOsdilep_OutZ_BoostedJets', channel='ElEl') plots += makeDileptonPlots(self, sel=hasOsMuMuOutZBoostedJets, dilepton=OsMuMu[0], suffix='hasOsdilep_OutZ_BoostedJets', channel='MuMu') plots += makeDileptonPlots(self, sel=hasOsElMuOutZBoostedJets, dilepton=OsElMu[0], suffix='hasOsdilep_OutZ_BoostedJets', channel='ElMu') plots += makeDileptonPlots(self, sel=hasOsMuElOutZBoostedJets, dilepton=OsMuEl[0], suffix='hasOsdilep_OutZ_BoostedJets', channel='MuEl') # Plotting the fatjet for OS dilepton, Z peak and Boosted jets selections # plots += makeFatJetPlots(self, sel=hasOsElElOutZBoostedJets, fatjet=bjetsBoosted[0], suffix="hasOsdilep_OutZ_BoostedJets", channel="ElEl") plots += makeFatJetPlots(self, sel=hasOsMuMuOutZBoostedJets, fatjet=bjetsBoosted[0], suffix="hasOsdilep_OutZ_BoostedJets", channel="MuMu") plots += makeFatJetPlots(self, sel=hasOsElMuOutZBoostedJets, fatjet=bjetsBoosted[0], suffix="hasOsdilep_OutZ_BoostedJets", channel="ElMu") plots += makeFatJetPlots(self, sel=hasOsMuElOutZBoostedJets, fatjet=bjetsBoosted[0], suffix="hasOsdilep_OutZ_BoostedJets", channel="MuEl") # Plotting the jets for OS dilepton, Z peak and Resolved jets selections # plots += makeJetsPlots(self, sel=hasOsElElOutZResolvedJets, jets=bjetsResolved, suffix="hasOsdilep_OutZ_ResolvedJets", channel="ElEl") plots += makeJetsPlots(self, sel=hasOsMuMuOutZResolvedJets, jets=bjetsResolved, suffix="hasOsdilep_OutZ_ResolvedJets", channel="MuMu") plots += makeJetsPlots(self, sel=hasOsElMuOutZResolvedJets, jets=bjetsResolved, suffix="hasOsdilep_OutZ_ResolvedJets", channel="ElMu") plots += makeJetsPlots(self, sel=hasOsMuElOutZResolvedJets, jets=bjetsResolved, suffix="hasOsdilep_OutZ_ResolvedJets", channel="MuEl") ## helper selection (OR) to make sure jet calculations are only done once #hasOSLL = noSel.refine("hasOSLL", cut=op.OR(*( hasOSLL_cmbRng(rng) for rng in osLLRng.values()))) #forceDefine(t._Jet.calcProd, hasOSLL) #for varNm in t._Jet.available: # forceDefine(t._Jet[varNm], hasOSLL) return plots
def definePlots(self, t, noSel, sample=None, sampleCfg=None): from bamboo.plots import Plot, CutFlowReport, EquidistantBinning, VariableBinning from bamboo import treefunctions as op plots = [] # definitions electrons = op.select( t.elec, lambda el: op.AND(el.pt > 20., op.abs(el.eta) < 2.5)) muons = op.select(t.muon, lambda mu: op.AND(mu.pt > 20., op.abs(mu.eta) < 2.5)) cleanedElectrons = op.select( electrons, lambda el: op.NOT( op.rng_any(muons, lambda mu: op.deltaR(el.p4, mu.p4) < 0.3))) # we are taking the second isopass to be on which is equal to the medium working point isolatedElectrons = op.select(cleanedElectrons, lambda el: el.isopass & (1 << 2)) identifiedElectrons = op.select(isolatedElectrons, lambda el: el.idpass & (1 << 2)) cleanedMuons = op.select( muons, lambda mu: op.NOT( op.rng_any(electrons, lambda el: op.deltaR(mu.p4, el.p4) < 0.3) )) isolatedMuons = op.select(cleanedMuons, lambda mu: mu.isopass & (1 << 2)) identifiedMuons = op.select(isolatedMuons, lambda mu: mu.idpass & (1 << 2)) cleanedJets = op.select( t.jetpuppi, lambda j: op.AND( op.NOT( op.rng_any(identifiedElectrons, lambda el: op.deltaR( el.p4, j.p4) < 0.3)), op.NOT( op.rng_any(identifiedMuons, lambda mu: op.deltaR( mu.p4, j.p4) < 0.3)))) cleanedGoodJets30_0to1_5 = op.select( cleanedJets, lambda j: op.AND(j.pt > 30, op.abs(j.eta) < 1.5)) cleanedGoodJets30_1_5to3 = op.select( cleanedJets, lambda j: op.AND( j.pt > 30, op.NOT(op.AND(op.abs(j.eta) < 1.5, op.abs(j.eta) > 3)))) cleanedGoodJets30_3toInf = op.select( cleanedJets, lambda j: op.AND(j.pt > 30, op.abs(j.eta) > 3)) cleanedGoodJets50_0to1_5 = op.select( cleanedJets, lambda j: op.AND(j.pt > 50, op.abs(j.eta) < 1.5)) cleanedGoodJets50_1_5to3 = op.select( cleanedJets, lambda j: op.AND( j.pt > 50, op.NOT(op.AND(op.abs(j.eta) < 1.5, op.abs(j.eta) > 3)))) cleanedGoodJets50_3toInf = op.select( cleanedJets, lambda j: op.AND(j.pt > 50, op.abs(j.eta) > 3)) cleanedGoodJets100_0to1_5 = op.select( cleanedJets, lambda j: op.AND(j.pt > 100, op.abs(j.eta) < 1.5)) cleanedGoodJets100_1_5to3 = op.select( cleanedJets, lambda j: op.AND( j.pt > 100, op.NOT(op.AND(op.abs(j.eta) < 1.5, op.abs(j.eta) > 3)))) cleanedGoodJets100_3toInf = op.select( cleanedJets, lambda j: op.AND(j.pt > 100, op.abs(j.eta) > 3)) cleanedGoodJets30 = op.select(cleanedJets, lambda j: j.pt > 30) cleanedGoodJets50 = op.select(cleanedJets, lambda j: j.pt > 50) cleanedGoodJets100 = op.select(cleanedJets, lambda j: j.pt > 100) met = op.select(t.metpuppi) sel1 = noSel.refine("nJet30", cut=[op.rng_len(cleanedGoodJets30) > 0]) sel2 = noSel.refine("nJet50", cut=[op.rng_len(cleanedGoodJets50) > 0]) sel3 = noSel.refine("nJet100", cut=[op.rng_len(cleanedGoodJets100) > 0]) sel1_1 = noSel.refine("nJet30_1", cut=[op.rng_len(cleanedGoodJets30) > 0]) sel1_1_1 = noSel.refine("nJet30_1_1", cut=[op.rng_len(cleanedGoodJets30_0to1_5) > 0]) sel1_1_2 = noSel.refine("nJet30_1_2", cut=[op.rng_len(cleanedGoodJets30_1_5to3) > 0]) sel1_1_3 = noSel.refine("nJet30_1_3", cut=[op.rng_len(cleanedGoodJets30_3toInf) > 0]) sel2_1 = noSel.refine("nJet50_1", cut=[op.rng_len(cleanedGoodJets50) > 0]) sel1_2_1 = noSel.refine("nJet50_1_1", cut=[op.rng_len(cleanedGoodJets50_0to1_5) > 0]) sel1_2_2 = noSel.refine("nJet50_1_2", cut=[op.rng_len(cleanedGoodJets50_1_5to3) > 0]) sel1_2_3 = noSel.refine("nJet50_1_3", cut=[op.rng_len(cleanedGoodJets50_3toInf) > 0]) sel3_1 = noSel.refine("nJet100_1", cut=[op.rng_len(cleanedGoodJets100) > 0]) sel1_3_1 = noSel.refine( "nJet100_1_1", cut=[op.rng_len(cleanedGoodJets100_0to1_5) > 0]) sel1_3_2 = noSel.refine( "nJet100_1_2", cut=[op.rng_len(cleanedGoodJets100_1_5to3) > 0]) sel1_3_3 = noSel.refine( "nJet100_1_3", cut=[op.rng_len(cleanedGoodJets100_3toInf) > 0]) sel1_2 = noSel.refine("nJet30_2", cut=[op.rng_len(cleanedGoodJets30) > 1]) sel2_1_1 = noSel.refine("nJet30_2_1", cut=[op.rng_len(cleanedGoodJets30_0to1_5) > 1]) sel2_1_2 = noSel.refine("nJet30_2_2", cut=[op.rng_len(cleanedGoodJets30_1_5to3) > 1]) sel2_1_3 = noSel.refine("nJet30_2_3", cut=[op.rng_len(cleanedGoodJets30_3toInf) > 1]) sel2_2 = noSel.refine("nJet50_2", cut=[op.rng_len(cleanedGoodJets50) > 1]) sel2_2_1 = noSel.refine("nJet50_2_1", cut=[op.rng_len(cleanedGoodJets50_0to1_5) > 1]) sel2_2_2 = noSel.refine("nJet50_2_2", cut=[op.rng_len(cleanedGoodJets50_1_5to3) > 1]) sel2_2_3 = noSel.refine("nJet50_2_3", cut=[op.rng_len(cleanedGoodJets50_3toInf) > 1]) sel3_2 = noSel.refine("nJet100_2", cut=[op.rng_len(cleanedGoodJets100) > 1]) sel2_3_1 = noSel.refine( "nJet100_2_1", cut=[op.rng_len(cleanedGoodJets100_0to1_5) > 1]) sel2_3_2 = noSel.refine( "nJet100_2_2", cut=[op.rng_len(cleanedGoodJets100_1_5to3) > 1]) sel2_3_3 = noSel.refine( "nJet100_2_3", cut=[op.rng_len(cleanedGoodJets100_3toInf) > 1]) sel1_3 = noSel.refine("nJet30_3", cut=[op.rng_len(cleanedGoodJets30) > 2]) sel3_1_1 = noSel.refine("nJet30_3_1", cut=[op.rng_len(cleanedGoodJets30_0to1_5) > 2]) sel3_1_2 = noSel.refine("nJet30_3_2", cut=[op.rng_len(cleanedGoodJets30_1_5to3) > 2]) sel3_1_3 = noSel.refine("nJet30_3_3", cut=[op.rng_len(cleanedGoodJets30_3toInf) > 2]) sel2_3 = noSel.refine("nJet50_3", cut=[op.rng_len(cleanedGoodJets50) > 2]) sel3_2_1 = noSel.refine("nJet50_3_1", cut=[op.rng_len(cleanedGoodJets50_0to1_5) > 2]) sel3_2_2 = noSel.refine("nJet50_3_2", cut=[op.rng_len(cleanedGoodJets50_1_5to3) > 2]) sel3_2_3 = noSel.refine("nJet50_3_3", cut=[op.rng_len(cleanedGoodJets50_3toInf) > 2]) sel3_3 = noSel.refine("nJet100_3", cut=[op.rng_len(cleanedGoodJets100) > 2]) sel3_3_1 = noSel.refine( "nJet100_3_1", cut=[op.rng_len(cleanedGoodJets100_0to1_5) > 2]) sel3_3_2 = noSel.refine( "nJet100_3_2", cut=[op.rng_len(cleanedGoodJets100_1_5to3) > 2]) sel3_3_3 = noSel.refine( "nJet100_3_3", cut=[op.rng_len(cleanedGoodJets100_3toInf) > 2]) sel1_4 = noSel.refine("nJet30_4", cut=[op.rng_len(cleanedGoodJets30) > 3]) sel4_1_1 = noSel.refine("nJet30_4_1", cut=[op.rng_len(cleanedGoodJets30_0to1_5) > 3]) sel4_1_2 = noSel.refine("nJet30_4_2", cut=[op.rng_len(cleanedGoodJets30_1_5to3) > 3]) sel4_1_3 = noSel.refine("nJet30_4_3", cut=[op.rng_len(cleanedGoodJets30_3toInf) > 3]) sel2_4 = noSel.refine("nJet50_4", cut=[op.rng_len(cleanedGoodJets50) > 3]) sel4_2_1 = noSel.refine("nJet50_4_1", cut=[op.rng_len(cleanedGoodJets50_0to1_5) > 3]) sel4_2_2 = noSel.refine("nJet50_4_2", cut=[op.rng_len(cleanedGoodJets50_1_5to3) > 3]) sel4_2_3 = noSel.refine("nJet50_4_3", cut=[op.rng_len(cleanedGoodJets50_3toInf) > 3]) sel3_4 = noSel.refine("nJet100_4", cut=[op.rng_len(cleanedGoodJets100) > 3]) sel4_3_1 = noSel.refine( "nJet100_4_1", cut=[op.rng_len(cleanedGoodJets100_0to1_5) > 3]) sel4_3_2 = noSel.refine( "nJet100_4_2", cut=[op.rng_len(cleanedGoodJets100_1_5to3) > 3]) sel4_3_3 = noSel.refine( "nJet100_4_3", cut=[op.rng_len(cleanedGoodJets100_3toInf) > 3]) # plots # # ### 30 GeV plots.append( Plot.make1D("nJets_jetPT_30GeV", op.rng_len(cleanedGoodJets30), noSel, EquidistantBinning(15, 0., 15.), title="nJets (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet1_pT_jetPT_30GeV", cleanedGoodJets30[0].pt, sel1_1, EquidistantBinning(50, 0., 4000.), title="Jet1_pT (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet1_eta_jetPT_30GeV", cleanedGoodJets30[0].eta, sel1_1, EquidistantBinning(30, -3, 3), title="Jet1_eta (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet1_pT_0to1_5_jetPT_30GeV", cleanedGoodJets30_0to1_5[0].pt, sel1_1_1, EquidistantBinning(50, 0, 4000), title="Jet1_pT 0 < eta < 1.5, (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet1_pT_1_5to3_jetPT_30GeV", cleanedGoodJets30_1_5to3[0].pt, sel1_1_2, EquidistantBinning(50, 0, 4000), title="Jet1_pT 1.5 < eta < 3, (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet1_pT_3toInf_jetPT_30GeV", cleanedGoodJets30_3toInf[0].pt, sel1_1_3, EquidistantBinning(50, 0, 1000), title="Jet1_pT eta > 3, (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet2_pT_jetPT_30GeV", cleanedGoodJets30[1].pt, sel1_2, EquidistantBinning(50, 0., 4000.), title="Jet2_pT (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet2_eta_jetPT_30GeV", cleanedGoodJets30[1].eta, sel1_2, EquidistantBinning(30, -3, 3), title="Jet2_eta (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet2_pT_0to1_5_jetPT_30GeV", cleanedGoodJets30_0to1_5[1].pt, sel2_1_1, EquidistantBinning(50, 0, 4000), title="Jet2_pT 0 < eta < 1.5, (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet2_pT_1_5to3_jetPT_30GeV", cleanedGoodJets30_1_5to3[1].pt, sel2_1_2, EquidistantBinning(50, 0, 4000), title="Jet2_pT 1.5 < eta < 3, (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet2_pT_3toInf_jetPT_30GeV", cleanedGoodJets30_3toInf[1].pt, sel2_1_3, EquidistantBinning(50, 0, 500), title="Jet2_pT eta > 3, (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet3_pT_jetPT_30GeV", cleanedGoodJets30[2].pt, sel1_3, EquidistantBinning(50, 0., 2000.), title="Jet3_pT (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet3_eta_jetPT_30GeV", cleanedGoodJets30[2].eta, sel1_3, EquidistantBinning(30, -3, 3), title="Jet3_eta (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet3_pT_0to1_5_jetPT_30GeV", cleanedGoodJets30_0to1_5[2].pt, sel3_1_1, EquidistantBinning(50, 0, 2000), title="Jet3_pT 0 < eta < 1.5, (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet3_pT_1_5to3_jetPT_30GeV", cleanedGoodJets30_1_5to3[2].pt, sel3_1_2, EquidistantBinning(50, 0, 2000), title="Jet3_pT 1.5 < eta < 3, (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet3_pT_3toInf_jetPT_30GeV", cleanedGoodJets30_3toInf[2].pt, sel3_1_3, EquidistantBinning(50, 0, 200), title="Jet3_pT eta > 3, (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet4_pT_jetPT_30GeV", cleanedGoodJets30[3].pt, sel1_4, EquidistantBinning(50, 0., 2000.), title="Jet4_pT (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet4_eta_jetPT_30GeV", cleanedGoodJets30[3].eta, sel1_4, EquidistantBinning(30, -3, 3), title="Jet4_eta (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet4_pT_0to1_5_jetPT_30GeV", cleanedGoodJets30_0to1_5[3].pt, sel4_1_1, EquidistantBinning(50, 0, 2000), title="Jet4_pT 0 < eta < 1.5, (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet4_pT_1_5to3_jetPT_30GeV", cleanedGoodJets30_1_5to3[3].pt, sel4_1_2, EquidistantBinning(50, 0, 2000), title="Jet4_pT 1.5 < eta < 3, (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet4_pT_3toInf_jetPT_30GeV", cleanedGoodJets30_3toInf[3].pt, sel4_1_3, EquidistantBinning(50, 0, 200), title="Jet4_pT eta > 3, (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("MET_jetPT_30GeV", met[0].pt, sel1, EquidistantBinning(50, 0, 1000), title="MET (jet p_{T} > 30GeV)")) # # ### 50 GeV plots.append( Plot.make1D("nJets_jetPT_50GeV", op.rng_len(cleanedGoodJets50), noSel, EquidistantBinning(15, 0., 15.), title="nJets (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet1_pT_jetPT_50GeV", cleanedGoodJets50[0].pt, sel2_1, EquidistantBinning(50, 0., 4000.), title="Jet1_pT (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet1_eta_jetPT_50GeV", cleanedGoodJets50[0].eta, sel2_1, EquidistantBinning(30, -3, 3), title="Jet1_eta (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet1_pT_0to1_5_jetPT_50GeV", cleanedGoodJets50_0to1_5[0].pt, sel1_2_1, EquidistantBinning(50, 0, 4000), title="Jet1_pT 0 < eta < 1.5, (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet1_pT_1_5to3_jetPT_50GeV", cleanedGoodJets50_1_5to3[0].pt, sel1_2_2, EquidistantBinning(50, 0, 4000), title="Jet1_pT 1.5 < eta < 3, (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet1_pT_3toInf_jetPT_50GeV", cleanedGoodJets50_3toInf[0].pt, sel1_2_3, EquidistantBinning(50, 0, 1000), title="Jet1_pT eta > 3, (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet2_pT_jetPT_50GeV", cleanedGoodJets50[1].pt, sel2_2, EquidistantBinning(50, 0., 4000.), title="Jet2_pT (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet2_eta_jetPT_50GeV", cleanedGoodJets50[1].eta, sel2_2, EquidistantBinning(30, -3, 3), title="Jet2_eta (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet2_pT_0to1_5_jetPT_50GeV", cleanedGoodJets50_0to1_5[1].pt, sel2_2_1, EquidistantBinning(50, 0, 4000), title="Jet2_pT 0 < eta < 1.5, (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet2_pT_1_5to3_jetPT_50GeV", cleanedGoodJets50_1_5to3[1].pt, sel2_2_2, EquidistantBinning(50, 0, 4000), title="Jet2_pT 1.5 < eta < 3, (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet2_pT_3toInf_jetPT_50GeV", cleanedGoodJets50_3toInf[1].pt, sel2_2_3, EquidistantBinning(50, 0, 500), title="Jet2_pT eta > 3, (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet3_pT_jetPT_50GeV", cleanedGoodJets50[2].pt, sel2_3, EquidistantBinning(50, 0., 2000.), title="Jet3_pT (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet3_eta_jetPT_50GeV", cleanedGoodJets50[2].eta, sel2_3, EquidistantBinning(30, -3, 3), title="Jet3_eta (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet3_pT_0to1_5_jetPT_50GeV", cleanedGoodJets50_0to1_5[2].pt, sel3_2_1, EquidistantBinning(50, 0, 2000), title="Jet3_pT 0 < eta < 1.5, (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet3_pT_1_5to3_jetPT_50GeV", cleanedGoodJets50_1_5to3[2].pt, sel3_2_2, EquidistantBinning(50, 0, 2000), title="Jet3_pT 1.5 < eta < 3, (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet3_pT_3toInf_jetPT_50GeV", cleanedGoodJets50_3toInf[2].pt, sel3_2_3, EquidistantBinning(50, 0, 200), title="Jet3_pT eta > 3, (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet4_pT_jetPT_50GeV", cleanedGoodJets50[3].pt, sel2_4, EquidistantBinning(50, 0., 2000.), title="Jet4_pT (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet4_eta_jetPT_50GeV", cleanedGoodJets50[3].eta, sel2_4, EquidistantBinning(30, -3, 3), title="Jet4_eta (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet4_pT_0to1_5_jetPT_50GeV", cleanedGoodJets50_0to1_5[3].pt, sel4_2_1, EquidistantBinning(50, 0, 2000), title="Jet4_pT 0 < eta < 1.5, (jet p_{T} > 30GeV)")) plots.append( Plot.make1D("Jet4_pT_1_5to3_jetPT_50GeV", cleanedGoodJets50_1_5to3[3].pt, sel4_2_2, EquidistantBinning(50, 0, 2000), title="Jet4_pT 1.5 < eta < 3, (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("Jet4_pT_3toInf_jetPT_50GeV", cleanedGoodJets50_3toInf[3].pt, sel4_2_3, EquidistantBinning(50, 0, 200), title="Jet4_pT eta > 3, (jet p_{T} > 50GeV)")) plots.append( Plot.make1D("MET_jetPT_50GeV", met[0].pt, sel2, EquidistantBinning(50, 0, 1000), title="MET (jet p_{T} > 50GeV)")) # ### 100 GeV plots.append( Plot.make1D("nJets_jetPT_100GeV", op.rng_len(cleanedGoodJets100), noSel, EquidistantBinning(15, 0., 15.), title="nJets (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet1_pT_jetPT_100GeV", cleanedGoodJets100[0].pt, sel3_1, EquidistantBinning(50, 0., 4000.), title="Jet1_pT (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet1_eta_jetPT_100GeV", cleanedGoodJets100[0].eta, sel3_1, EquidistantBinning(30, -3, 3), title="Jet1_eta (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet1_pT_0to1_5_jetPT_100GeV", cleanedGoodJets100_0to1_5[0].pt, sel1_3_1, EquidistantBinning(50, 0, 4000), title="Jet1_pT 0 < eta < 1.5, (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet1_pT_1_5to3_jetPT_100GeV", cleanedGoodJets100_1_5to3[0].pt, sel1_3_2, EquidistantBinning(50, 0, 4000), title="Jet1_pT 1.5 < eta < 3, (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet1_pT_3toInf_jetPT_100GeV", cleanedGoodJets100_3toInf[0].pt, sel1_3_3, EquidistantBinning(50, 0, 1000), title="Jet1_pT eta > 3, (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet2_pT_jetPT_100GeV", cleanedGoodJets100[1].pt, sel3_2, EquidistantBinning(50, 0., 4000.), title="Jet2_pT (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet2_eta_jetPT_100GeV", cleanedGoodJets100[1].eta, sel3_2, EquidistantBinning(30, -3, 3), title="Jet2_eta (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet2_pT_0to1_5_jetPT_100GeV", cleanedGoodJets100_0to1_5[1].pt, sel2_3_1, EquidistantBinning(50, 0, 4000), title="Jet2_pT 0 < eta < 1.5, (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet2_pT_1_5to3_jetPT_100GeV", cleanedGoodJets100_1_5to3[1].pt, sel2_3_2, EquidistantBinning(50, 0, 4000), title="Jet2_pT 1.5 < eta < 3, (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet2_pT_3toInf_jetPT_100GeV", cleanedGoodJets100_3toInf[1].pt, sel2_3_3, EquidistantBinning(50, 0, 500), title="Jet2_pT eta > 3, (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet3_pT_jetPT_100GeV", cleanedGoodJets100[2].pt, sel3_3, EquidistantBinning(50, 0., 2000.), title="Jet3_pT (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet3_eta_jetPT_100GeV", cleanedGoodJets100[2].eta, sel3_3, EquidistantBinning(30, -3, 3), title="Jet3_eta (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet3_pT_0to1_5_jetPT_100GeV", cleanedGoodJets100_0to1_5[2].pt, sel3_3_1, EquidistantBinning(50, 0, 2000), title="Jet3_pT 0 < eta < 1.5, (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet3_pT_1_5to3_jetPT_100GeV", cleanedGoodJets100_1_5to3[2].pt, sel3_3_2, EquidistantBinning(50, 0, 2000), title="Jet3_pT 1.5 < eta < 3, (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet3_pT_3toInf_jetPT_100GeV", cleanedGoodJets100_3toInf[2].pt, sel3_3_3, EquidistantBinning(50, 0, 200), title="Jet3_pT eta > 3, (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet4_pT_jetPT_100GeV", cleanedGoodJets100[3].pt, sel3_4, EquidistantBinning(50, 0., 2000.), title="Jet4_pT (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet4_eta_jetPT_100GeV", cleanedGoodJets100[3].eta, sel3_4, EquidistantBinning(30, -3, 3), title="Jet4_eta (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet4_pT_0to1_5_jetPT_100GeV", cleanedGoodJets100_0to1_5[3].pt, sel4_3_1, EquidistantBinning(50, 0, 2000), title="Jet4_pT 0 < eta < 1.5, (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet4_pT_1_5to3_jetPT_100GeV", cleanedGoodJets100_1_5to3[3].pt, sel4_3_2, EquidistantBinning(50, 0, 2000), title="Jet4_pT 1.5 < eta < 3, (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("Jet4_pT_3toInf_jetPT_100GeV", cleanedGoodJets100_3toInf[3].pt, sel4_3_3, EquidistantBinning(50, 0, 200), title="Jet4_pT eta > 3, (jet p_{T} > 100GeV)")) plots.append( Plot.make1D("MET_jetPT_100GeV", met[0].pt, sel3, EquidistantBinning(50, 0, 1000), title="MET (jet p_{T} > 100GeV)")) # Efficiency Report on terminal and the .tex output cfr = CutFlowReport("yields") cfr.add(noSel, "None") cfr.add(sel1, "30GeV") cfr.add(sel2, "50GeV") cfr.add(sel3, "100GeV") plots.append(cfr) return plots
def definePlots(self, tree, noSel, sample=None, sampleCfg=None): from bamboo.plots import Plot, SummedPlot from bamboo.plots import EquidistantBinning as EqBin from bamboo import treefunctions as op if self.args.examples == "all": examples = list(i+1 for i in range(self.nExamples)) # 1-4 are fine, so is 7 else: examples = list(set(int(tk) for tk in self.args.examples.split(","))) logger.info("Running the following examples: {0}".format(",".join(str(i) for i in examples))) plots = [] if 1 in examples: ## Example 1: Plot the missing ET of all events. plots.append(Plot.make1D("Ex1_MET", tree.MET.pt, noSel, EqBin(100, 0., 2000.), title="MET (GeV)")) if 2 in examples: ## Example 2: Plot pT of all jets in all events. plots.append(Plot.make1D("Ex2_jetPt", op.map(tree.Jet, lambda j : j.pt), noSel, EqBin(100, 15., 60.), title="Jet p_{T} (GeV/c)")) if 3 in examples: ## Example 3: Plot pT of jets with |η| < 1. centralJets1 = op.select(tree.Jet, lambda j : op.abs(j.eta) < 1.) plots.append(Plot.make1D("Ex3_central1_jetPt", op.map(centralJets1, lambda j : j.pt), noSel, EqBin(100, 15., 60.), title="Jet p_{T} (GeV/c)")) if 4 in examples: ## Example 4: Plot the missing ET of events that have at least two jets with pT > 40 GeV. jets40 = op.select(tree.Jet, lambda j : j.pt > 40) hasTwoJets40 = noSel.refine("twoJets40", cut=(op.rng_len(jets40) >= 2)) plots.append(Plot.make1D("Ex4_twoJets40_MET", tree.MET.pt, hasTwoJets40, EqBin(100, 0., 2000.), title="MET (GeV)")) if 5 in examples: ## Example 5: Plot the missing ET of events that have an opposite-sign muon pair with an invariant mass between 60 and 120 GeV. dimu_Z = op.combine(tree.Muon, N=2, pred=(lambda mu1, mu2 : op.AND( mu1.charge != mu2.charge, op.in_range(60., op.invariant_mass(mu1.p4, mu2.p4), 120.) ))) hasDiMuZ = noSel.refine("hasDiMuZ", cut=(op.rng_len(dimu_Z) > 0)) plots.append(Plot.make1D("Ex5_dimuZ_MET", tree.MET.pt, hasDiMuZ, EqBin(100, 0., 2000.), title="MET (GeV)")) if 6 in examples: ## Example 6: Plot pT of the trijet system with the mass closest to 172.5 GeV in each event and plot the maximum b-tagging discriminant value among the jets in the triplet. trijets = op.combine(tree.Jet, N=3) hadTop = op.rng_min_element_by(trijets, fun=lambda comb: op.abs((comb[0].p4+comb[1].p4+comb[2].p4).M()-172.5)) hadTop_p4 = (hadTop[0].p4 + hadTop[1].p4 + hadTop[2].p4) hasTriJet = noSel.refine("hasTriJet", cut=(op.rng_len(trijets) > 0)) plots.append(Plot.make1D("Ex6_trijet_topPt", hadTop_p4.Pt(), hasTriJet, EqBin(100, 15., 40.), title="Trijet p_{T} (GeV/c)")) plots.append(Plot.make1D("Ex6_trijet_maxbtag", op.max(op.max(hadTop[0].btag, hadTop[1].btag), hadTop[2].btag), hasTriJet, EqBin(100, 0., 1.), title="Trijet maximum b-tag")) if verbose: plots.append(Plot.make1D("Ex6_njets", op.rng_len(tree.Jet), noSel, EqBin(20, 0., 20.), title="Number of jets")) plots.append(Plot.make1D("Ex6_ntrijets", op.rng_len(trijets), noSel, EqBin(100, 0., 1000.), title="Number of 3-jet combinations")) plots.append(Plot.make1D("Ex6_trijet_mass", hadTop_p4.M(), hasTriJet, EqBin(100, 0., 250.), title="Trijet mass (GeV/c^{2})")) if 7 in examples: ## Example 7: Plot the sum of pT of jets with pT > 30 GeV that are not within 0.4 in ΔR of any lepton with pT > 10 GeV. el10 = op.select(tree.Electron, lambda el : el.pt > 10.) mu10 = op.select(tree.Muon , lambda mu : mu.pt > 10.) cleanedJets30 = op.select(tree.Jet, lambda j : op.AND( j.pt > 30., op.NOT(op.rng_any(el10, lambda el : op.deltaR(j.p4, el.p4) < 0.4 )), op.NOT(op.rng_any(mu10, lambda mu : op.deltaR(j.p4, mu.p4) < 0.4 )) )) plots.append(Plot.make1D("Ex7_sumCleanedJetPt", op.rng_sum(cleanedJets30, lambda j : j.pt), noSel, EqBin(100, 15., 200.), title="Sum p_{T} (GeV/c)")) if 8 in examples: ## Example 8: For events with at least three leptons and a same-flavor opposite-sign lepton pair, find the same-flavor opposite-sign lepton pair with the mass closest to 91.2 GeV and plot the transverse mass of the missing energy and the leading other lepton. # The plot is made for each of the different flavour categories (l+/- l-/+ l') and then summed, # because concatenation of containers is not (yet) supported. lepColl = { "El" : tree.Electron, "Mu" : tree.Muon } mt3lPlots = [] for dlNm,dlCol in lepColl.items(): dilep = op.combine(dlCol, N=2, pred=(lambda l1,l2 : op.AND(l1.charge != l2.charge))) hasDiLep = noSel.refine("hasDilep{0}{0}".format(dlNm), cut=(op.rng_len(dilep) > 0)) dilepZ = op.rng_min_element_by(dilep, fun=lambda ll : op.abs(op.invariant_mass(ll[0].p4, ll[1].p4)-91.2)) for tlNm,tlCol in lepColl.items(): if tlCol == dlCol: hasTriLep = hasDiLep.refine("hasTrilep{0}{0}{1}".format(dlNm,tlNm), cut=(op.rng_len(tlCol) > 2)) residLep = op.select(tlCol, lambda l : op.AND(l.idx != dilepZ[0].idx, l.idx != dilepZ[1].idx)) l3 = op.rng_max_element_by(residLep, lambda l : l.pt) else: hasTriLep = hasDiLep.refine("hasTriLep{0}{0}{1}".format(dlNm,tlNm), cut=(op.rng_len(tlCol) > 0)) l3 = op.rng_max_element_by(tlCol, lambda l : l.pt) mtPlot = Plot.make1D("Ex8_3lMT_{0}{0}{1}".format(dlNm,tlNm), op.sqrt(2*l3.pt*tree.MET.pt*(1-op.cos(l3.phi-tree.MET.phi))), hasTriLep, EqBin(100, 15., 250.), title="M_{T} (GeV/c^2)") mt3lPlots.append(mtPlot) plots.append(mtPlot) plots.append(SummedPlot("Ex8_3lMT", mt3lPlots)) return plots
def returnHighLevelMVAInputs(self,l1,l2,met,jets,bjets,electrons,muons,channel): if channel == "ElEl": cone_l1 = self.getElectronConeP4(l1) cone_l2 = self.getElectronConeP4(l2) elif channel == "MuMu": cone_l1 = self.getMuonConeP4(l1) cone_l2 = self.getMuonConeP4(l2) elif channel == "ElMu": cone_l1 = self.getElectronConeP4(l1) cone_l2 = self.getMuonConeP4(l2) else: raise RuntimeError("Wrong channel") dijets = op.combine(jets, N=2) import bamboo.treeoperations as _to def rng_min(rng, fun=(lambda x : x), typeName="float"): return op._to.Reduce.fromRngFun(rng, op.c_float(float("+inf"), typeName), ( lambda fn : ( lambda res, elm : op.extMethod("std::min", returnType="Float_t")(res, fn(elm)) ) )(fun) ) if self.args.Boosted0Btag or self.args.Boosted1Btag: VBFJetPairs = self.VBFJetPairsBoosted elif self.args.Resolved0Btag or self.args.Resolved1Btag or self.args.Resolved2Btag: VBFJetPairs = self.VBFJetPairsResolved else: raise RuntimeError("Wrong selection to be used by the DNN") return { ('m_bb_bregcorr', 'Di-bjet invariant mass (regcorr) [GeV]', (100,0.,1000.)) : op.multiSwitch((op.rng_len(bjets) == 0, op.c_float(0.)), (op.rng_len(bjets) == 1, self.HLL.getCorrBp4(bjets[0]).M()), op.invariant_mass(self.HLL.getCorrBp4(bjets[0]),self.HLL.getCorrBp4(bjets[1]))), ('ht', 'HT(jets) [GeV]', (100,0.,1000.)) : op.rng_sum(jets, lambda j : j.pt), ('min_dr_jets_lep1', 'Min(#Delta R(lead lepton,jets))', (25,0.,5.)) : op.switch(op.rng_len(jets) > 0, op.switch(cone_l1.Pt() >= cone_l2.Pt(), self.HLL.MinDR_part1_partCont(cone_l1,jets), self.HLL.MinDR_part1_partCont(cone_l2,jets)), op.c_float(0.)), ('min_dr_jets_lep2', 'Min(#Delta R(sublead lepton,jets))', (25,0.,5.)) : op.switch(op.rng_len(jets) > 0, op.switch(cone_l1.Pt() >= cone_l2.Pt(), self.HLL.MinDR_part1_partCont(cone_l2,jets), self.HLL.MinDR_part1_partCont(cone_l1,jets)), op.c_float(0.)), ('m_ll', 'Dilepton invariant mass [GeV]', (100,0.,1000.)) : op.invariant_mass(cone_l1,cone_l2), ('dr_ll', 'Dilepton #Delta R', (25,0.,5.)) : op.deltaR(cone_l1,cone_l2), ('min_dr_jet', 'Min(#Delta R(jets))', (25,0.,5.)) : op.switch(op.rng_len(dijets) > 0, op.rng_min(dijets,lambda dijet : op.deltaR(dijet[0].p4,dijet[1].p4)), op.c_float(0.)), ('min_dhi_jet', 'Min(#Delta #Phi(jets))', (16,0.,3.2)) : op.switch(op.rng_len(dijets) > 0, rng_min(dijets,lambda dijet : op.abs(op.deltaPhi(dijet[0].p4,dijet[1].p4)),typeName='double'), op.c_float(0.)), ('m_hh_simplemet_bregcorr','M_{HH} (simple MET) (regcorr) [GeV]', (100,0.,1000.)) : op.invariant_mass(op.rng_sum(bjets, lambda bjet : self.HLL.getCorrBp4(bjet), start=self.HLL.empty_p4), cone_l1, cone_l2, met.p4), ('met_ld', 'MET_{LD}', (100,0.,1000.)) : self.HLL.MET_LD_DL(met,jets,electrons,muons), ('dr_bb', 'Di-bjet #Delta R', (25,0.,5.)) : op.switch(op.rng_len(bjets)>=2, op.deltaR(bjets[0].p4,bjets[1].p4), op.c_float(0.)), ('min_dr_leps_b1', 'Min(#Delta R(lead bjet,dilepton))', (25,0.,5.)) : op.switch(op.rng_len(bjets)>=1, self.HLL.MinDR_part1_dipart(bjets[0].p4,[cone_l1,cone_l2]), op.c_float(0.)), ('min_dr_leps_b2', 'Min(#Delta R(sublead bjet,dilepton))', (25,0.,5.)) : op.switch(op.rng_len(bjets)>=2, self.HLL.MinDR_part1_dipart(bjets[1].p4,[cone_l1,cone_l2]), op.c_float(0.)), ('lep1_conept', 'Lead lepton cone-P_T [GeV]', (40,0.,200.)) : op.switch(cone_l1.Pt() >= cone_l2.Pt() , cone_l1.Pt() , cone_l2.Pt()), ('lep2_conept', 'Sublead lepton cone-P_T [GeV]', (40,0.,200.)) : op.switch(cone_l1.Pt() >= cone_l2.Pt() , cone_l2.Pt() , cone_l1.Pt()), ('mww_simplemet', 'M_{WW} (simple MET) [GeV]', (100,0.,1000.)) : op.invariant_mass(cone_l1,cone_l2,met.p4), ('vbf_tag', 'VBF tag', (2,0.,2.)) : op.c_int(op.rng_len(VBFJetPairs)>0), ('boosted_tag', 'Boosted tag', (2,0.,2.)) : op.c_int(op.OR(op.rng_len(self.ak8BJets) > 0, # Boosted 1B op.AND(op.rng_len(self.ak8BJets) == 0, # Boosted 0B op.rng_len(self.ak8Jets) > 0, op.rng_len(self.ak4BJets) == 0))), ('dphi_met_dilep', 'Dilepton-MET #Delta #Phi', (32,-3.2,3.2)) : op.abs(op.deltaPhi(met.p4,(cone_l1+cone_l2))), ('dphi_met_dibjet', 'Dibjet-MET #Delta #Phi', (32,-3.2,3.2)) : op.multiSwitch((op.rng_len(bjets) == 0, op.c_float(0.)), (op.rng_len(bjets) == 1, op.abs(op.deltaPhi(met.p4,bjets[0].p4))), op.abs(op.deltaPhi(met.p4,(bjets[0].p4+bjets[1].p4)))), ('dr_dilep_dijet', 'Dilepton-dijet #Delta R', (25,0.,5.)) : op.multiSwitch((op.rng_len(jets) == 0, op.c_float(0.)), (op.rng_len(jets) == 1, op.deltaR((cone_l1+cone_l2),jets[0].p4)), op.deltaR((cone_l1+cone_l2),(jets[0].p4+jets[1].p4))), ('dr_dilep_dibjet', 'Dilepton-dibjet #Delta R', (25,0.,5.)) : op.multiSwitch((op.rng_len(bjets) == 0, op.c_float(0.)), (op.rng_len(bjets) == 1, op.deltaR((cone_l1+cone_l2),bjets[0].p4)), op.deltaR((cone_l1+cone_l2),(bjets[0].p4+bjets[1].p4))), ('vbf_pair_mass', 'VBF pair M_{jj}', (100,0.,1000.)) : op.switch(op.rng_len(VBFJetPairs)>0, op.invariant_mass(VBFJetPairs[0][0].p4,VBFJetPairs[0][1].p4), op.c_float(0.)), ('vbf_pairs_absdeltaeta', 'VBF pair #Delta#eta', (25,0.,5.)) : op.switch(op.rng_len(VBFJetPairs)>0, op.abs(VBFJetPairs[0][0].eta-VBFJetPairs[0][1].eta), op.c_float(0.)), ('sphericity', 'None', (1,0.,1.)) : op.c_float(0.), ('sphericity_T', 'None', (1,0.,1.)) : op.c_float(0.), ('aplanarity', 'None', (1,0.,1.)) : op.c_float(0.), ('eventshape_C', 'None', (1,0.,1.)) : op.c_float(0.), ('eventshape_D', 'None', (1,0.,1.)) : op.c_float(0.), ('eventshape_Y', 'None', (1,0.,1.)) : op.c_float(0.), ('foxwolfram1', 'None', (1,0.,1.)) : op.c_float(0.), ('foxwolfram2', 'None', (1,0.,1.)) : op.c_float(0.), ('foxwolfram3', 'None', (1,0.,1.)) : op.c_float(0.), ('foxwolfram4', 'None', (1,0.,1.)) : op.c_float(0.), ('foxwolfram5', 'None', (1,0.,1.)) : op.c_float(0.), ('centrality', 'None', (1,0.,1.)) : op.c_float(0.), ('centrality_jets', 'None', (1,0.,1.)) : op.c_float(0.), ('eigenvalue1', 'None', (1,0.,1.)) : op.c_float(0.), ('eigenvalue2', 'None', (1,0.,1.)) : op.c_float(0.), ('eigenvalue3', 'None', (1,0.,1.)) : op.c_float(0.), }
def definePlots(self, t, noSel, sample=None, sampleCfg=None): era = sampleCfg['era'] plots = [] ########################################################## # Leptons # ########################################################## #----- Gen particles -----# gen_e_minus = op.select( t.GenPart, lambda g: op.AND(g.pdgId == 11, g.statusFlags & (0x1 << 13), g.pt > 10, op.abs(g.eta) < 2.5)) gen_e_plus = op.select( t.GenPart, lambda g: op.AND(g.pdgId == -11, g.statusFlags & (0x1 << 13), g.pt > 10, op.abs(g.eta) < 2.5)) gen_mu_minus = op.select( t.GenPart, lambda g: op.AND(g.pdgId == 13, g.statusFlags & (0x1 << 13), g.pt > 10, op.abs(g.eta) < 2.4)) gen_mu_plus = op.select( t.GenPart, lambda g: op.AND(g.pdgId == -13, g.statusFlags & (0x1 << 13), g.pt > 10, op.abs(g.eta) < 2.4)) plots.extend( plotNumber("N_e_minus_gen", gen_e_minus, noSel, 10, "N(e^{-}) gen level")) plots.extend( plotNumber("N_e_plus_gen", gen_e_plus, noSel, 10, "N(e^{+}) gen level")) plots.extend( plotNumber("N_mu_minus_gen", gen_mu_minus, noSel, 10, "N(\mu^{-}) gen level")) plots.extend( plotNumber("N_mu_plus_gen", gen_mu_plus, noSel, 10, "N(\mu^{+}) gen level")) #----- Reco particles -----# reco_e_minus = op.select( t.Electron, lambda ele: op.AND( ele.charge == -1, ele.pdgId == 11, ele.pt > 10, op.abs(ele.eta) < 2.5, op.OR(ele.genPartFlav == 1, ele.genPartFlav == 15, ele. genPartFlav == 22))) reco_e_plus = op.select( t.Electron, lambda ele: op.AND( ele.charge == +1, ele.pdgId == -11, ele.pt > 10, op.abs(ele.eta) < 2.5, op.OR(ele.genPartFlav == 1, ele.genPartFlav == 15, ele. genPartFlav == 22))) reco_mu_minus = op.select( t.Muon, lambda mu: op.AND( mu.charge == -1, mu.pdgId == 13, mu.pt > 10, op.abs(mu.eta) < 2.4, op.OR(mu.genPartFlav == 1, mu.genPartFlav == 15))) reco_mu_plus = op.select( t.Muon, lambda mu: op.AND( mu.charge == +1, mu.pdgId == -13, mu.pt > 10, op.abs(mu.eta) < 2.4, op.OR(mu.genPartFlav == 1, mu.genPartFlav == 15))) plots.extend( plotNumber("N_e_minus_reco", reco_e_minus, noSel, 10, "N(e^{-}) reco level")) plots.extend( plotNumber("N_e_plus_reco", reco_e_plus, noSel, 10, "N(e^{+}) reco level")) plots.extend( plotNumber("N_mu_minus_reco", reco_mu_minus, noSel, 10, "N(\mu^{-}) reco level")) plots.extend( plotNumber("N_mu_plus_reco", reco_mu_plus, noSel, 10, "N(\mu^{+}) reco level")) #---- Matching -----# lambda_lepton_match = lambda l_gen, l_reco: op.AND( op.deltaR(l_gen.p4, l_reco.p4) < 0.1, op.abs(l_gen.pt - l_reco.pt) / l_gen.pt < 0.2) match_e_minus = op.combine((gen_e_minus, reco_e_minus), pred=lambda_lepton_match) match_e_plus = op.combine((gen_e_plus, reco_e_plus), pred=lambda_lepton_match) match_mu_minus = op.combine((gen_mu_minus, reco_mu_minus), pred=lambda_lepton_match) match_mu_plus = op.combine((gen_mu_plus, reco_mu_plus), pred=lambda_lepton_match) SelEMinusMatch = noSel.refine("SelEMinusMatch", cut=[op.rng_len(match_e_minus) >= 1]) SelEPlusMatch = noSel.refine("SelEPlusMatch", cut=[op.rng_len(match_e_plus) >= 1]) SelMuMinusMatch = noSel.refine("SelMuMinusMatch", cut=[op.rng_len(match_mu_minus) >= 1]) SelMuPlusMatch = noSel.refine("SelMuPlusMatch", cut=[op.rng_len(match_mu_plus) >= 1]) plots.extend( plotNumber("N_e_minus_match", match_e_minus, noSel, 10, "N(e^{-}) match level")) plots.extend( plotNumber("N_e_plus_match", match_e_plus, noSel, 10, "N(e^{+}) match level")) plots.extend( plotNumber("N_mu_minus_match", match_mu_minus, noSel, 10, "N(\mu^{-}) match level")) plots.extend( plotNumber("N_mu_plus_match", match_mu_plus, noSel, 10, "N(\mu^{+}) match level")) plots.extend( plotMatching("e", [match_e_minus, match_e_plus], [SelEMinusMatch, SelEPlusMatch], "e^{#pm}")) plots.extend( plotMatching("mu", [match_mu_minus, match_mu_plus], [SelMuMinusMatch, SelMuPlusMatch], "#mu^{#pm}")) ########################################################## # B jets # ########################################################## #----- RecoJets -----# #recoJet_b = op.select(t.Jet, lambda j : op.AND(j.partonFlavour == 5, j.pt>10, op.abs(j.eta)<2.4 ,(op.abs(j.pt-j.genJet.pt)/j.genJet.pt)<1 )) #recoJet_bbar = op.select(t.Jet, lambda j : op.AND(j.partonFlavour == -5, j.pt>10, op.abs(j.eta)<2.4 ,(op.abs(j.pt-j.genJet.pt)/j.genJet.pt)<1 )) recoJet_b = op.select( t.Jet, lambda j: op.AND(j.partonFlavour == 5, j.pt > 10, op.abs(j.eta) < 2.4, j.genJet.isValid)) recoJet_bbar = op.select( t.Jet, lambda j: op.AND(j.partonFlavour == -5, j.pt > 10, op.abs(j.eta) < 2.4, j.genJet.isValid)) plots.extend( plotNumber("N_jetb_reco", recoJet_b, noSel, 5, "N(b) reco jet")) plots.extend( plotNumber("N_jetbbar_reco", recoJet_bbar, noSel, 5, "N(#bar{b}) reco jet")) SelBReco = noSel.refine("SelBReco", cut=[op.rng_len(recoJet_b) >= 1]) SelBBarReco = noSel.refine("SelBBarReco", cut=[op.rng_len(recoJet_bbar) >= 1]) # plots.extend(plotJetReco("bjet",recoJet_b,SelBReco,"b jet")) # plots.extend(plotJetReco("bbarjet",recoJet_bbar,SelBBarReco,"#bar{b} jet")) # # # #----- Parton -----# # gen_b = op.select(t.GenPart,lambda g : op.AND( g.pdgId==5 , g.statusFlags & ( 0x1 << 13) , g.pt>10, op.abs(g.eta)<2.4)) # gen_bbar = op.select(t.GenPart,lambda g : op.AND( g.pdgId==-5 , g.statusFlags & ( 0x1 << 13) , g.pt>10, op.abs(g.eta)<2.4)) # plots.extend(plotNumber("N_b_gen",gen_b,noSel,5,"N(b) gen quark")) # plots.extend(plotNumber("N_bbar_gen",gen_bbar,noSel,5,"N(#bar{b}) gen quark")) # # #----- Matching -----# # lambda_bjet_match = lambda b_gen,b_jet : op.deltaR(b_gen.p4,b_jet.genJet.p4)<0.2 # # match_b = op.combine((gen_b,recoJet_b),pred=lambda_bjet_match) # match_bbar = op.combine((gen_bbar,recoJet_bbar),pred=lambda_bjet_match) # # plots.extend(plotNumber("N_b_match",match_b,noSel,5,"N(b) match level")) # plots.extend(plotNumber("N_bbar_match",match_bbar,noSel,5,"N(#bar{b}) match level")) # # SelBMatch = noSel.refine("SelBMatch",cut=[op.rng_len(match_b)>=1]) # SelBBarMatch = noSel.refine("SelBBarMatch",cut=[op.rng_len(match_bbar)>=1]) # # plots.extend(plotMatching("b",[match_b,match_bbar],[SelBMatch,SelBBarMatch],"b")) return plots
def returnResonantMVAInputs(self, l1, l2, channel, jets, bjets, fatjets, met, electrons, muons): if channel == "ElEl": l1conept = lambda l1: self.electron_conept[l1.idx] l2conept = lambda l2: self.electron_conept[l2.idx] elif channel == "MuMu": l1conept = lambda l1: self.muon_conept[l1.idx] l2conept = lambda l2: self.muon_conept[l2.idx] elif channel == "ElMu": l1conept = lambda l1: self.electron_conept[l1.idx] l2conept = lambda l2: self.muon_conept[l2.idx] else: raise RuntimeError("Wrong channel") dijets = op.combine(jets, N=2) import bamboo.treeoperations as _to def rng_min(rng, fun=(lambda x: x), typeName="float"): return op._to.Reduce.fromRngFun( rng, op.c_float(float("+inf"), typeName), (lambda fn: (lambda res, elm: op.extMethod("std::min", returnType="Float_t") (res, fn(elm))))(fun)) if self.args.era is None: era = op.c_int(int(self.era)) else: era = op.c_int(int(self.args.era)) print(f'Using {self.args.era} as DNN input') return { ('eventnr', 'Event number', (100, 0., 1e6)): self.tree.event, ('era', 'Era', (3, 2016., 2019.)): era, ('l1_E', 'Lead lepton E [GeV]', (50, 0., 500.)): op.switch(l1conept(l1) >= l2conept(l2), l1.p4.E(), l2.p4.E()), ('l1_Px', 'Lead lepton P_x [GeV]', (40, -200., 200.)): op.switch(l1conept(l1) >= l2conept(l2), l1.p4.Px(), l2.p4.Px()), ('l1_Py', 'Lead lepton P_y [GeV]', (40, -200., 200.)): op.switch(l1conept(l1) >= l2conept(l2), l1.p4.Py(), l2.p4.Py()), ('l1_Pz', 'Lead lepton P_z [GeV]', (40, -200., 200.)): op.switch(l1conept(l1) >= l2conept(l2), l1.p4.Pz(), l2.p4.Pz()), ('l1_charge', 'Lead lepton charge', (2, 0., 2.)): op.switch(l1conept(l1) >= l2conept(l2), l1.charge, l2.charge), ('l1_pdgId', 'Lead lepton pdg ID', (45, -22., 22.)): op.switch(l1conept(l1) >= l2conept(l2), l1.pdgId, l2.pdgId), ('l2_E', 'Sublead lepton E [GeV]', (50, 0., 500.)): op.switch(l1conept(l1) >= l2conept(l2), l2.p4.E(), l1.p4.E()), ('l2_Px', 'Sublead lepton P_x [GeV]', (40, -200., 200.)): op.switch(l1conept(l1) >= l2conept(l2), l2.p4.Px(), l1.p4.Px()), ('l2_Py', 'Sublead lepton P_y [GeV]', (40, -200., 200.)): op.switch(l1conept(l1) >= l2conept(l2), l2.p4.Py(), l1.p4.Py()), ('l2_Pz', 'Sublead lepton P_z [GeV]', (40, -200., 200.)): op.switch(l1conept(l1) >= l2conept(l2), l2.p4.Pz(), l1.p4.Pz()), ('l2_charge', 'Sublead lepton charge', (2, 0., 2.)): op.switch(l1conept(l1) >= l2conept(l2), l2.charge, l1.charge), ('l2_pdgId', 'Sublead lepton pdg ID', (45, -22., 22.)): op.switch(l1conept(l1) >= l2conept(l2), l2.pdgId, l1.pdgId), ('j1_E', 'Lead jet E [GeV]', (50, 0., 500.)): op.switch(op.rng_len(jets) > 0, jets[0].p4.E(), op.c_float(0.)), ('j1_Px', 'Lead jet P_x [GeV]', (40, -200., 200.)): op.switch(op.rng_len(jets) > 0, jets[0].p4.Px(), op.c_float(0.)), ('j1_Py', 'Lead jet P_y [GeV]', (40, -200., 200.)): op.switch(op.rng_len(jets) > 0, jets[0].p4.Py(), op.c_float(0.)), ('j1_Pz', 'Lead jet P_z [GeV]', (40, -200., 200.)): op.switch(op.rng_len(jets) > 0, jets[0].p4.Pz(), op.c_float(0.)), ('j2_E', 'Sublead jet E [GeV]', (50, 0., 500.)): op.switch(op.rng_len(jets) > 1, jets[1].p4.E(), op.c_float(0.)), ('j2_Px', 'Sublead jet P_x [GeV]', (40, -200., 200.)): op.switch(op.rng_len(jets) > 1, jets[1].p4.Px(), op.c_float(0.)), ('j2_Py', 'Sublead jet P_y [GeV]', (40, -200., 200.)): op.switch(op.rng_len(jets) > 1, jets[1].p4.Py(), op.c_float(0.)), ('j2_Pz', 'Sublead jet P_z [GeV]', (40, -200., 200.)): op.switch(op.rng_len(jets) > 1, jets[1].p4.Pz(), op.c_float(0.)), ('j3_E', 'Subsublead jet E [GeV]', (50, 0., 500.)): op.switch(op.rng_len(jets) > 2, jets[2].p4.E(), op.c_float(0.)), ('j3_Px', 'Subsublead jet P_x [GeV]', (40, -200., 200.)): op.switch(op.rng_len(jets) > 2, jets[2].p4.Px(), op.c_float(0.)), ('j3_Py', 'Subsublead jet P_y [GeV]', (40, -200., 200.)): op.switch(op.rng_len(jets) > 2, jets[2].p4.Py(), op.c_float(0.)), ('j3_Pz', 'Subsublead jet P_z [GeV]', (40, -200., 200.)): op.switch(op.rng_len(jets) > 2, jets[2].p4.Pz(), op.c_float(0.)), ('j4_E', 'Subsubsublead jet E [GeV]', (50, 0., 500.)): op.switch(op.rng_len(jets) > 3, jets[3].p4.E(), op.c_float(0.)), ('j4_Px', 'Subsubsublead jet P_x [GeV]', (40, -200., 200.)): op.switch(op.rng_len(jets) > 3, jets[3].p4.Px(), op.c_float(0.)), ('j4_Py', 'Subsubsublead jet P_y [GeV]', (40, -200., 200.)): op.switch(op.rng_len(jets) > 3, jets[3].p4.Py(), op.c_float(0.)), ('j4_Pz', 'Subsubsublead jet P_z [GeV]', (40, -200., 200.)): op.switch(op.rng_len(jets) > 3, jets[3].p4.Pz(), op.c_float(0.)), ('fatjet_E', 'Fatjet E [GeV]', (50, 0., 500.)): op.switch(op.rng_len(fatjets) > 0, fatjets[0].p4.E(), op.c_float(0.)), ('fatjet_Px', 'Fatjet P_x [GeV]', (40, -200., 200.)): op.switch(op.rng_len(fatjets) > 0, fatjets[0].p4.Px(), op.c_float(0.)), ('fatjet_Py', 'Fatjet P_y [GeV]', (40, -200., 200.)): op.switch(op.rng_len(fatjets) > 0, fatjets[0].p4.Py(), op.c_float(0.)), ('fatjet_Pz', 'Fatjet P_z [GeV]', (40, -200., 200.)): op.switch(op.rng_len(fatjets) > 0, fatjets[0].p4.Pz(), op.c_float(0.)), ('fatjet_tau1', 'Fatjet #tau_1', (50, 0., 1.)): op.switch(op.rng_len(fatjets) > 0, fatjets[0].tau1, op.c_float(0.)), ('fatjet_tau2', 'Fatjet #tau_2', (50, 0., 1.)): op.switch(op.rng_len(fatjets) > 0, fatjets[0].tau2, op.c_float(0.)), ('fatjet_tau3', 'Fatjet #tau_3', (50, 0., 1.)): op.switch(op.rng_len(fatjets) > 0, fatjets[0].tau3, op.c_float(0.)), ('fatjet_tau4', 'Fatjet #tau_4', (50, 0., 1.)): op.switch(op.rng_len(fatjets) > 0, fatjets[0].tau4, op.c_float(0.)), ('fatjet_softdrop', 'Fatjet softdrop mass [GeV]', (50, 0., 1000.)): op.switch( op.rng_len(fatjets) > 0, fatjets[0].msoftdrop, op.c_float(0.)), ('met_E', 'MET Energy', (50, 0., 500.)): met.p4.E(), ('met_Px', 'MET P_x', (40, -200., 200.)): met.p4.Px(), ('met_Py', 'MET P_y', (40, -200., 200.)): met.p4.Py(), ('met_Pz', 'MET P_z', (40, -200., 200.)): met.p4.Pz(), ('m_bb_bregcorr', 'Di-bjet invariant mass (regcorr) [GeV]', (100, 0., 1000.)): op.multiSwitch( (op.rng_len(bjets) == 0, op.c_float(0.)), (op.rng_len(bjets) == 1, self.HLL.getCorrBp4(bjets[0]).M()), op.invariant_mass(self.HLL.getCorrBp4(bjets[0]), self.HLL.getCorrBp4(bjets[1]))), ('ht', 'HT(jets) [GeV]', (100, 0., 1000.)): op.rng_sum(jets, lambda j: j.pt), ('min_dr_jets_lep1', 'Min(#Delta R(lead lepton,jets))', (25, 0., 5.)): op.switch( op.rng_len(jets) > 0, op.switch( l1conept(l1) >= l2conept(l2), self.HLL.MinDR_part1_partCont(l1.p4, jets), self.HLL.MinDR_part1_partCont(l2.p4, jets)), op.c_float(0.)), ('min_dr_jets_lep2', 'Min(#Delta R(sublead lepton,jets))', (25, 0., 5.)): op.switch( op.rng_len(jets) > 0, op.switch( l1conept(l1) >= l2conept(l2), self.HLL.MinDR_part1_partCont(l2.p4, jets), self.HLL.MinDR_part1_partCont(l1.p4, jets)), op.c_float(0.)), ('m_ll', 'Dilepton invariant mass [GeV]', (100, 0., 1000.)): op.invariant_mass(l1.p4, l2.p4), ('dr_ll', 'Dilepton #Delta R', (25, 0., 5.)): op.deltaR(l1.p4, l2.p4), ('min_dr_jet', 'Min(#Delta R(jets))', (25, 0., 5.)): op.switch( op.rng_len(dijets) > 0, op.rng_min(dijets, lambda dijet: op.deltaR(dijet[0].p4, dijet[1].p4)), op.c_float(0.)), ('min_dphi_jet', 'Min(#Delta #Phi(jets))', (16, 0., 3.2)): op.switch( op.rng_len(dijets) > 0, rng_min( dijets, lambda dijet: op.abs(op.deltaPhi(dijet[0].p4, dijet[1].p4)), typeName='double'), op.c_float(0.)), ('m_hh_simplemet_bregcorr', 'M_{HH} (simple MET) (regcorr) [GeV]', (100, 0., 1000.)): op.invariant_mass( op.rng_sum(bjets, lambda bjet: self.HLL.getCorrBp4(bjet), start=self.HLL.empty_p4), l1.p4, l2.p4, met.p4), ('met_ld', 'MET_{LD}', (100, 0., 1000.)): self.HLL.MET_LD_DL(met, jets, electrons, muons), ('dr_bb', 'Di-bjet #Delta R', (25, 0., 5.)): op.switch( op.rng_len(bjets) >= 2, op.deltaR(bjets[0].p4, bjets[1].p4), op.c_float(0.)), ('min_dr_leps_b1', 'Min(#Delta R(lead bjet,dilepton))', (25, 0., 5.)): op.switch( op.rng_len(bjets) >= 1, self.HLL.MinDR_part1_dipart(bjets[0].p4, [l1.p4, l2.p4]), op.c_float(0.)), ('min_dr_leps_b2', 'Min(#Delta R(sublead bjet,dilepton))', (25, 0., 5.)): op.switch( op.rng_len(bjets) >= 2, self.HLL.MinDR_part1_dipart(bjets[1].p4, [l1.p4, l2.p4]), op.c_float(0.)), ('lep1_conept', 'Lead lepton cone-P_T [GeV]', (40, 0., 200.)): op.switch(l1conept(l1) >= l2conept(l2), l1conept(l1), l2conept(l2)), ('lep2_conept', 'Sublead lepton cone-P_T [GeV]', (40, 0., 200.)): op.switch(l1conept(l1) >= l2conept(l2), l2conept(l2), l1conept(l1)), ('mww_simplemet', 'M_{WW} (simple MET) [GeV]', (100, 0., 1000.)): op.invariant_mass(l1.p4, l2.p4, met.p4), ('boosted_tag', 'Boosted tag', (2, 0., 2.)): op.c_int( op.OR( op.rng_len(self.ak8BJets) > 0, # Boosted 1B op.AND( op.rng_len(self.ak8BJets) == 0, # Boosted 0B op.rng_len(self.ak8Jets) > 0, op.rng_len(self.ak4BJets) == 0))), ('dphi_met_dilep', 'Dilepton-MET #Delta #Phi', (32, -3.2, 3.2)): op.abs(op.deltaPhi(met.p4, (l1.p4 + l2.p4))), ('dphi_met_dibjet', 'Dibjet-MET #Delta #Phi', (32, -3.2, 3.2)): op.multiSwitch( (op.rng_len(bjets) == 0, op.c_float(0.)), (op.rng_len(bjets) == 1, op.abs(op.deltaPhi(met.p4, bjets[0].p4))), op.abs(op.deltaPhi(met.p4, (bjets[0].p4 + bjets[1].p4)))), ('dr_dilep_dijet', 'Dilepton-dijet #Delta R', (25, 0., 5.)): op.multiSwitch( (op.rng_len(jets) == 0, op.c_float(0.)), (op.rng_len(jets) == 1, op.deltaR((l1.p4 + l2.p4), jets[0].p4)), op.deltaR((l1.p4 + l2.p4), (jets[0].p4 + jets[1].p4))), ('dr_dilep_dibjet', 'Dilepton-dibjet #Delta R', (25, 0., 5.)): op.multiSwitch( (op.rng_len(bjets) == 0, op.c_float(0.)), (op.rng_len(bjets) == 1, op.deltaR((l1.p4 + l2.p4), bjets[0].p4)), op.deltaR((l1.p4 + l2.p4), (bjets[0].p4 + bjets[1].p4))), ('m_T', 'Transverse mass', (100, 0., 1000.)): op.sqrt(2 * (l1.p4 + l2.p4).Pt() * met.p4.E() * (1 - op.cos((l1.p4 + l2.p4).Phi() - met.p4.Phi()))), ('cosThetaS_Hbb', 'Helicity angle between Hbb and bjet', (20, 0., 1.)): op.switch( op.rng_len(bjets) == 2, op.extMethod("HHbbWWJPA::cosThetaS", returnType="float")(bjets[0].p4, bjets[1].p4), op.c_float(0.)), ('LBN_inputs', 'LBN inputs', None): [ op.switch(l1conept(l1) >= l2conept(l2), l1.p4.E(), l2.p4.E()), op.switch(l1conept(l1) >= l2conept(l2), l1.p4.Px(), l2.p4.Px()), op.switch(l1conept(l1) >= l2conept(l2), l1.p4.Py(), l2.p4.Py()), op.switch(l1conept(l1) >= l2conept(l2), l1.p4.Pz(), l2.p4.Pz()), op.switch(l1conept(l1) >= l2conept(l2), l2.p4.E(), l1.p4.E()), op.switch(l1conept(l1) >= l2conept(l2), l2.p4.Px(), l1.p4.Px()), op.switch(l1conept(l1) >= l2conept(l2), l2.p4.Py(), l1.p4.Py()), op.switch(l1conept(l1) >= l2conept(l2), l2.p4.Pz(), l1.p4.Pz()), op.switch(op.rng_len(jets) > 0, jets[0].p4.E(), op.c_float(0.)), op.switch(op.rng_len(jets) > 0, jets[0].p4.Px(), op.c_float(0.)), op.switch(op.rng_len(jets) > 0, jets[0].p4.Py(), op.c_float(0.)), op.switch(op.rng_len(jets) > 0, jets[0].p4.Pz(), op.c_float(0.)), op.switch(op.rng_len(jets) > 1, jets[1].p4.E(), op.c_float(0.)), op.switch(op.rng_len(jets) > 1, jets[1].p4.Px(), op.c_float(0.)), op.switch(op.rng_len(jets) > 1, jets[1].p4.Py(), op.c_float(0.)), op.switch(op.rng_len(jets) > 1, jets[1].p4.Pz(), op.c_float(0.)), op.switch(op.rng_len(jets) > 2, jets[2].p4.E(), op.c_float(0.)), op.switch(op.rng_len(jets) > 2, jets[2].p4.Px(), op.c_float(0.)), op.switch(op.rng_len(jets) > 2, jets[2].p4.Py(), op.c_float(0.)), op.switch(op.rng_len(jets) > 2, jets[2].p4.Pz(), op.c_float(0.)), op.switch(op.rng_len(jets) > 3, jets[3].p4.E(), op.c_float(0.)), op.switch(op.rng_len(jets) > 3, jets[3].p4.Px(), op.c_float(0.)), op.switch(op.rng_len(jets) > 3, jets[3].p4.Py(), op.c_float(0.)), op.switch(op.rng_len(jets) > 3, jets[3].p4.Pz(), op.c_float(0.)), op.switch( op.rng_len(fatjets) > 0, fatjets[0].p4.E(), op.c_float(0.)), op.switch( op.rng_len(fatjets) > 0, fatjets[0].p4.Px(), op.c_float(0.)), op.switch( op.rng_len(fatjets) > 0, fatjets[0].p4.Py(), op.c_float(0.)), op.switch( op.rng_len(fatjets) > 0, fatjets[0].p4.Pz(), op.c_float(0.)) ] }
def definePlots(self, t, noSel, sample=None, sampleCfg=None): from bamboo.analysisutils import forceDefine from bamboo.plots import Plot from bamboo.plots import EquidistantBinning as EqB from bamboo import treefunctions as op era = sampleCfg.get("era") if sampleCfg else None noSel = noSel.refine("passMETFlags", cut=METFilter(t.Flag, era) ) puWeightsFile = None if era == "2016": sfTag="94X" puWeightsFile = os.path.join(os.path.dirname(__file__), "data/PileupFullRunII", "puweights2016.json") elif era == "2017": sfTag="94X" puWeightsFile = os.path.join(os.path.dirname(__file__), "data/PileupFullRunII", "puweights2017.json") elif era == "2018": sfTag="102X" puWeightsFile = os.path.join(os.path.dirname(__file__), "data/PileupFullRunII", "puweights2018.json") if self.isMC(sample) and puWeightsFile is not None: from bamboo.analysisutils import makePileupWeight noSel = noSel.refine("puWeight", weight=makePileupWeight(puWeightsFile, t.Pileup_nTrueInt, systName="pileup")) isMC = self.isMC(sample) plots = [] forceDefine(t._Muon.calcProd, noSel) # Wp // 2016- 2017 -2018 : Muon_mediumId // https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideMuonIdRun2#Muon_Isolation #To suppress nonprompt lep-tons, the impact parameter in three dimensions of the lepton track, with respect to the primaryvertex, is required to be less than 4 times its uncertainty (|SIP3D|<4) sorted_muons = op.sort(t.Muon, lambda mu : -mu.pt) muons = op.select(sorted_muons, lambda mu : op.AND(mu.pt > 10., op.abs(mu.eta) < 2.4, mu.mediumId, mu.pfRelIso04_all<0.15, op.abs(mu.sip3d < 4.))) # i pass 2016 seprate from 2017 &2018 because SFs need to be combined for BCDEF and GH eras ! if era=="2016": doubleMuTrigSF = get_scalefactor("dilepton", ("doubleMuLeg_HHMoriond17_2016"), systName="mumutrig") muMediumIDSF = get_scalefactor("lepton", ("muon_{0}_{1}".format(era, sfTag), "id_medium"), combine="weight", systName="muid") muMediumISOSF = get_scalefactor("lepton", ("muon_{0}_{1}".format(era, sfTag), "iso_tight_id_medium"), combine="weight", systName="muiso") else: doubleMuTrigSF = get_scalefactor("dilepton", ("doubleMuLeg_HHMoriond17_2016"), systName="mumutrig") muMediumIDSF = get_scalefactor("lepton", ("muon_{0}_{1}".format(era, sfTag), "id_medium"), systName="muid") muMediumISOSF = get_scalefactor("lepton", ("muon_{0}_{1}".format(era, sfTag), "iso_tight_id_medium"), systName="muiso") #Wp // 2016: Electron_cutBased_Sum16==3 -> medium // 2017 -2018 : Electron_cutBased ==3 --> medium ( Fall17_V2) # asking for electrons to be in the Barrel region with dz<1mm & dxy< 0.5mm // Endcap region dz<2mm & dxy< 0.5mm # cut-based ID Fall17 V2 the recomended one from POG for the FullRunII sorted_electrons = op.sort(t.Electron, lambda ele : -ele.pt) electrons = op.select(sorted_electrons, lambda ele : op.AND(ele.pt > 15., op.abs(ele.eta) < 2.5 , ele.cutBased>=3, op.abs(ele.sip3d)< 4., op.OR(op.AND(op.abs(ele.dxy) < 0.05, op.abs(ele.dz) < 0.1), op.AND(op.abs(ele.dxy) < 0.05, op.abs(ele.dz) < 0.2) ))) elMediumIDSF = get_scalefactor("lepton", ("electron_{0}_{1}".format(era,sfTag), "id_medium"), systName="elid") doubleEleTrigSF = get_scalefactor("dilepton", ("doubleEleLeg_HHMoriond17_2016"), systName="eleltrig") elemuTrigSF = get_scalefactor("dilepton", ("elemuLeg_HHMoriond17_2016"), systName="elmutrig") mueleTrigSF = get_scalefactor("dilepton", ("mueleLeg_HHMoriond17_2016"), systName="mueltrig") MET = t.MET if era != "2017" else t.METFixEE2017 corrMET=METcorrection(MET,t.PV,sample,era,self.isMC(sample)) ####### select jets ################################## #// 2016 - 2017 - 2018 ( j.jetId &2) -> tight jet ID # For 2017 data, there is the option of "Tight" or "TightLepVeto", depending on how much you want to veto jets that overlap with/are faked by leptons sorted_AK4jets=op.sort(t.Jet, lambda j : -j.pt) AK4jetsSel = op.select(sorted_AK4jets, lambda j : op.AND(j.pt > 20., op.abs(j.eta)< 2.4, (j.jetId &2)))# j.jetId == 6))# oldcut: (j.jetId &2))) # exclude from the jetsSel any jet that happens to include within its reconstruction cone a muon or an electron. AK4jets= op.select(AK4jetsSel, lambda j : op.AND(op.NOT(op.rng_any(electrons, lambda ele : op.deltaR(j.p4, ele.p4) < 0.3 )), op.NOT(op.rng_any(muons, lambda mu : op.deltaR(j.p4, mu.p4) < 0.3 )))) # order jets by *decreasing* deepFlavour cleaned_AK4JetsByDeepFlav = op.sort(AK4jets, lambda j: -j.btagDeepFlavB) cleaned_AK4JetsByDeepB = op.sort(AK4jets, lambda j: -j.btagDeepB) # Boosted Region sorted_AK8jets=op.sort(t.FatJet, lambda j : -j.pt) AK8jetsSel = op.select(sorted_AK8jets, lambda j : op.AND(j.pt > 200., op.abs(j.eta)< 2.4, (j.jetId &2), j.subJet1._idx.result != -1, j.subJet2._idx.result != -1)) AK8jets= op.select(AK8jetsSel, lambda j : op.AND(op.NOT(op.rng_any(electrons, lambda ele : op.deltaR(j.p4, ele.p4) < 0.3 )), op.NOT(op.rng_any(muons, lambda mu : op.deltaR(j.p4, mu.p4) < 0.3 )))) cleaned_AK8JetsByDeepB = op.sort(AK8jets, lambda j: -j.btagDeepB) # Now, let's ask for the jets to be a b-jets # DeepCSV or deepJet Medium b-tag working point btagging = { "DeepCSV":{ # era: (loose, medium, tight) "2016":(0.2217, 0.6321, 0.8953), "2017":(0.1522, 0.4941, 0.8001), "2018":(0.1241, 0.4184, 0.7527) }, "DeepFlavour":{ "2016":(0.0614, 0.3093, 0.7221), "2017":(0.0521, 0.3033, 0.7489), "2018":(0.0494, 0.2770, 0.7264) } } # bjets ={ "DeepFlavour": {"L": jets pass loose , "M": jets pass medium , "T":jets pass tight } # "DeepCSV": {"L": --- , "M": --- , "T": ---- } # } # FIXME bjets_boosted = {} bjets_resolved = {} #WorkingPoints = ["L", "M", "T"] WorkingPoints = ["M"] for tagger in btagging.keys(): bJets_AK4_deepflavour ={} bJets_AK4_deepcsv ={} bJets_AK8_deepcsv ={} # FIXME idx is not propagated properly when i pass only one or two wp !! for wp in sorted(WorkingPoints): suffix = ("loose" if wp=='L' else ("medium" if wp=='M' else "tight")) idx = ( 0 if wp=="L" else ( 1 if wp=="M" else 2)) if tagger=="DeepFlavour": print ("Btagging: Era= {0}, Tagger={1}, Pass_{2}_working_point={3}".format(era, tagger, suffix, btagging[tagger][era][idx] )) print ("***********************************************", idx, wp) print ("btag_{0}_94X".format(era).replace("94X", "102X" if era=="2018" else "94X"), "{0}_{1}".format('DeepJet', suffix)) bJets_AK4_deepflavour[wp] = op.select(cleaned_AK4JetsByDeepFlav, lambda j : j.btagDeepFlavB >= btagging[tagger][era][idx] ) Jet_DeepFlavourBDisc = { "BTagDiscri": lambda j : j.btagDeepFlavB } deepBFlavScaleFactor = get_scalefactor("jet", ("btag_{0}_94X".format(era).replace("94X", "102X" if era=="2018" else "94X"), "{0}_{1}".format('DeepJet', suffix)), additionalVariables=Jet_DeepFlavourBDisc, getFlavour=(lambda j : j.hadronFlavour), systName="btagging{0}".format(era)) bjets_resolved[tagger]=bJets_AK4_deepflavour else: print ("Btagging: Era= {0}, Tagger={1}, Pass_{2}_working_point={3}".format(era, tagger, suffix, btagging[tagger][era][idx] )) print ("***********************************************", idx, wp) print ("btag_{0}_94X".format(era).replace("94X", "102X" if era=="2018" else "94X"), "{0}_{1}".format('DeepCSV', suffix)) bJets_AK4_deepcsv[wp] = op.select(cleaned_AK4JetsByDeepB, lambda j : j.btagDeepB >= btagging[tagger][era][idx] ) bJets_AK8_deepcsv[wp] = op.select(cleaned_AK8JetsByDeepB, lambda j : op.AND(j.subJet1.btagDeepB >= btagging[tagger][era][idx] , j.subJet2.btagDeepB >= btagging[tagger][era][idx])) Jet_DeepCSVBDis = { "BTagDiscri": lambda j : j.btagDeepB } subJet_DeepCSVBDis = { "BTagDiscri": lambda j : op.AND(j.subJet1.btagDeepB, j.subJet2.btagDeepB) } # FIXME for boosted and resolved i will use # tagger need to pass jsons files to scale factors above ! deepB_AK4ScaleFactor = get_scalefactor("jet", ("btag_{0}_94X".format(era).replace("94X", "102X" if era=="2018" else "94X"), "{0}_{1}".format('DeepCSV', suffix)), additionalVariables=Jet_DeepCSVBDis, getFlavour=(lambda j : j.hadronFlavour), systName="btagging{0}".format(era)) # FIXME #deepB_AK8ScaleFactor = get_scalefactor("jet", ("btag_{0}_94X".format(era).replace("94X", "102X" if era=="2018" else "94X"), "subjet_{0}_{1}".format('DeepCSV', suffix)), #additionalVariables=Jet_DeepCSVBDis, #getFlavour=(lambda j : j.subJet1.hadronFlavour), #systName="btagging{0}".format(era)) bjets_resolved[tagger]=bJets_AK4_deepcsv bjets_boosted[tagger]=bJets_AK8_deepcsv bestDeepFlavourPair={} bestDeepCSVPair={} bestJetPairs= {} bjets = {} # For the Resolved only class GetBestJetPair(object): JetsPair={} def __init__(self, JetsPair, tagger, wp): def ReturnHighestDiscriminatorJet(tagger, wp): if tagger=="DeepCSV": return op.sort(safeget(bjets_resolved, tagger, wp), lambda j: - j.btagDeepB) elif tagger=="DeepFlavour": return op.sort(safeget(bjets_resolved, tagger, wp), lambda j: - j.btagDeepFlavB) else: raise RuntimeError("Something went wrong in returning {0} discriminator !".format(tagger)) firstBest=ReturnHighestDiscriminatorJet(tagger, wp)[0] JetsPair[0]=firstBest secondBest=ReturnHighestDiscriminatorJet(tagger, wp)[1] JetsPair[1]=secondBest # bestJetPairs= { "DeepFlavour": bestDeepFlavourPair, # "DeepCSV": bestDeepCSVPair # } ####### Zmass reconstruction : Opposite Sign , Same Flavour leptons ######################################################## # supress quaronika resonances and jets misidentified as leptons LowMass_cut = lambda dilep: op.invariant_mass(dilep[0].p4, dilep[1].p4)>12. ## Dilepton selection: opposite sign leptons in range 70.<mll<120. GeV osdilep_Z = lambda l1,l2 : op.AND(l1.charge != l2.charge, op.in_range(70., op.invariant_mass(l1.p4, l2.p4), 120.)) osLLRng = { "MuMu" : op.combine(muons, N=2, pred= osdilep_Z), "ElEl" : op.combine(electrons, N=2, pred=osdilep_Z), #"ElMu" : op.combine((electrons, muons), pred=lambda ele,mu : op.AND(osdilep_Z(ele,mu), ele.pt > mu.pt )), #"MuEl" : op.combine((muons, electrons), pred=lambda mu,ele : op.AND(osdilep_Z(mu,ele), mu.pt > ele.pt)) } hasOSLL_cmbRng = lambda cmbRng : op.AND(op.rng_len(cmbRng) > 0, cmbRng[0][0].pt > 25.) # TODO The leading pT for the µµ channel should be above 20 Gev ! ## helper selection (OR) to make sure jet calculations are only done once hasOSLL = noSel.refine("hasOSLL", cut=op.OR(*( hasOSLL_cmbRng(rng) for rng in osLLRng.values()))) forceDefine(t._Jet.calcProd, hasOSLL) forceDefine(getattr(t, "_{0}".format("MET" if era != "2017" else "METFixEE2017")).calcProd, hasOSLL) llSFs = { "MuMu" : (lambda ll : [ muMediumIDSF(ll[0]), muMediumIDSF(ll[1]), muMediumISOSF(ll[0]), muMediumISOSF(ll[1]), doubleMuTrigSF(ll) ]), "ElMu" : (lambda ll : [ elMediumIDSF(ll[0]), muMediumIDSF(ll[1]), muMediumISOSF(ll[1]), elemuTrigSF(ll) ]), "MuEl" : (lambda ll : [ muMediumIDSF(ll[0]), muMediumISOSF(ll[0]), elMediumIDSF(ll[1]), mueleTrigSF(ll) ]), "ElEl" : (lambda ll : [ elMediumIDSF(ll[0]), elMediumIDSF(ll[1]), doubleEleTrigSF(ll) ]) } categories = dict((channel, (catLLRng[0], hasOSLL.refine("hasOS{0}".format(channel), cut=hasOSLL_cmbRng(catLLRng), weight=(llSFs[channel](catLLRng[0]) if isMC else None)) )) for channel, catLLRng in osLLRng.items()) ## btagging efficiencies plots #plots.extend(MakeBtagEfficienciesPlots(self, jets, bjets, categories)) for channel, (dilepton, catSel) in categories.items(): #---- Zmass (2Lepton OS && SF ) -------- #plots.extend(MakeControlPlotsForZpic(self, catSel, dilepton, channel)) #---- add Jets selection TwoLeptonsTwoJets_Resolved = catSel.refine("TwoJet_{0}Sel_resolved".format(channel), cut=[ op.rng_len(AK4jets) > 1 ]) TwoLeptonsTwoJets_Boosted = catSel.refine("OneJet_{0}Sel_boosted".format(channel), cut=[ op.rng_len(AK8jets) > 0 ]) #plots.extend(makeJetPlots(self, TwoLeptonsTwoJets_Resolved, AK4jets, channel)) #plots.extend(makeBoostedJetPLots(self, TwoLeptonsTwoJets_Boosted, AK8jets, channel)) # ----- plots : mll, mlljj, mjj, nVX, pT, eta : basic selection plots ------ #plots.extend(MakeControlPlotsForBasicSel(self, TwoLeptonsTwoJets_Resolved, AK4jets, dilepton, channel)) #plots.extend(MakeControlPlotsForBasicSel(self, TwoLeptonsTwoJets_boosted, AK8jets, dilepton, channel)) for wp in WorkingPoints: # Get the best AK4 JETS GetBestJetPair(bestDeepCSVPair,"DeepCSV", wp) GetBestJetPair(bestDeepFlavourPair,"DeepFlavour", wp) bestJetPairs["DeepCSV"]=bestDeepCSVPair bestJetPairs["DeepFlavour"]=bestDeepFlavourPair print ("bestJetPairs AK4--->", bestJetPairs, wp) print ("bestJetPairs_deepcsv AK4--->", bestJetPairs["DeepCSV"][0], bestJetPairs["DeepCSV"][1], wp) print ("bestJetPairs_deepflavour AK4 --->", bestJetPairs["DeepFlavour"][0],bestJetPairs["DeepFlavour"][1], wp) # resolved bJets_resolved_PassdeepflavourWP=safeget(bjets_resolved, "DeepFlavour", wp) bJets_resolved_PassdeepcsvWP=safeget(bjets_resolved, "DeepCSV", wp) # boosted bJets_boosted_PassdeepcsvWP=safeget(bjets_boosted, "DeepCSV", wp) TwoLeptonsTwoBjets_NoMETCut_Res = { "DeepFlavour{0}".format(wp) : TwoLeptonsTwoJets_Resolved.refine("TwoLeptonsTwoBjets_NoMETcut_DeepFlavour{0}_{1}_Resolved".format(wp, channel), cut=[ op.rng_len(bJets_resolved_PassdeepflavourWP) > 1 ], weight=([ deepBFlavScaleFactor(bJets_resolved_PassdeepflavourWP[0]), deepBFlavScaleFactor(bJets_resolved_PassdeepflavourWP[1]) ]if isMC else None)), "DeepCSV{0}".format(wp) : TwoLeptonsTwoJets_Resolved.refine("TwoLeptonsTwoBjets_NoMETcut_DeepCSV{0}_{1}_Resolved".format(wp, channel), cut=[ op.rng_len(bJets_resolved_PassdeepcsvWP) > 1 ], weight=([ deepB_AK4ScaleFactor(bJets_resolved_PassdeepcsvWP[0]), deepB_AK4ScaleFactor(bJets_resolved_PassdeepcsvWP[1]) ]if isMC else None)) } TwoLeptonsTwoBjets_NoMETCut_Boo = { "DeepCSV{0}".format(wp) : TwoLeptonsTwoJets_Boosted.refine("TwoLeptonsTwoBjets_NoMETcut_DeepCSV{0}_{1}_Boosted".format(wp, channel), cut=[ op.rng_len(bJets_boosted_PassdeepcsvWP) > 1 ]), # FIXME ! can't pass boosted jets SFs with current version ---> move to v7 #weight=([ deepB_AK8ScaleFactor(bJets_boosted_PassdeepcsvWP[0]), deepB_AK8ScaleFactor(bJets_boosted_PassdeepcsvWP[1]) ]if isMC else None)) } ## needed to optimize the MET cut # FIXME Rerun again &&& pass signal and bkg # The MET cut is passed to TwoLeptonsTwoBjets selection for the # tagger and for the # wp plots.extend(MakeMETPlots(self, TwoLeptonsTwoBjets_NoMETCut_Res, corrMET, MET, channel, "resolved")) plots.extend(MakeMETPlots(self, TwoLeptonsTwoBjets_NoMETCut_Boo, corrMET, MET, channel, "boosted")) plots.extend(MakeExtraMETPlots(self, TwoLeptonsTwoBjets_NoMETCut_Res, dilepton, MET, channel, "resolved")) plots.extend(MakeExtraMETPlots(self, TwoLeptonsTwoBjets_NoMETCut_Boo, dilepton, MET, channel, "boosted")) TwoLeptonsTwoBjets_Res = dict((key, selNoMET.refine("TwoLeptonsTwoBjets_{0}_{1}_Resolved".format(key, channel), cut=[ corrMET.pt < 80. ])) for key, selNoMET in TwoLeptonsTwoBjets_NoMETCut_Res.items()) TwoLeptonsTwoBjets_Boo = dict((key, selNoMET.refine("TwoLeptonsTwoBjets_{0}_{1}_Boosted".format(key, channel), cut=[ corrMET.pt < 80. ])) for key, selNoMET in TwoLeptonsTwoBjets_NoMETCut_Boo.items()) #plots.extend(MakeDiscriminatorPlots(self, TwoLeptonsTwoBjets_Res, bjets_resolved, wp, channel, "resolved")) #plots.extend(MakeDiscriminatorPlots(self, TwoLeptonsTwoBjets_Boo, bjets_boosted, wp, channel, "boosted")) #plots.extend(makeResolvedBJetPlots(self, TwoLeptonsTwoBjets_Res, bjets_resolved, dilepton, wp, channel)) #plots.extend(makeBoostedBJetPlots(self, TwoLeptonsTwoBjets_NoMETCut_Boo, bjets_boosted, dilepton, wp, channel)) # --- to get the Ellipses plots plots.extend(MakeEllipsesPLots(self, TwoLeptonsTwoBjets_Res, bjets_resolved, dilepton, wp, channel, "resolved")) plots.extend(MakeEllipsesPLots(self, TwoLeptonsTwoBjets_Boo, bjets_boosted, dilepton, wp, channel, "boosted")) return plots
def definePlots(self, t, noSel, sample=None, sampleCfg=None): from bamboo.plots import Plot, CutFlowReport, SummedPlot from bamboo.plots import EquidistantBinning as EqB from bamboo import treefunctions as op isMC = self.isMC(sample) trigCut, trigWeight = None, None if isMC: noSel = noSel.refine("mcWeight", weight=[ t.genWeight, t.puWeight, t.PrefireWeight ]) trigCut = op.OR(t.HLT.HIEle20_Ele12_CaloIdL_TrackIdL_IsoVL_DZ, t.HLT.HIL3DoubleMu0, t.HLT.HIL3Mu20, t.HLT.HIEle20_WPLoose_Gsf) ## TODO add a correction for prescaled triggers else: ## suggested trigger order: dielectron, dimuon or single muon, single electron (to minimise loss due to prescales). Electron triggered-events should be taken from the HighEGJet primary datasets, muon-triggered events from the SingleMuon primary datset pd = sample.split("_")[0] if pd == "SingleMuon": ## TODO fill trigger cut elif pd == "HighEGJet": ## TODO fill trigger cut noSel = noSel.refine("trig", cut=trigCut, weight=trigWeight) plots = [] goodLeptons = { "el" : op.select(t.Electron, partial(isGoodElectron, ptCut=15.)), "mu" : op.select(t.Muon, partial(isGoodMuon, ptCut=15.)) } plots += [ Plot.make1D("trig_nLeptons15", op.rng_len(goodLeptons["el"])+op.rng_len(goodLeptons["mu"]), noSel, EqB(15, 0., 15.)), Plot.make1D("trig_nEl15", op.rng_len(goodLeptons["el"]), noSel, EqB(15, 0., 15.)), Plot.make1D("trig_nMu15", op.rng_len(goodLeptons["mu"]), noSel, EqB(15, 0., 15.)) ] from bamboo.scalefactors import get_scalefactor sf_loose = { "mu": get_scalefactor("lepton", "Muon_RecoToLoose", sfLib=scalefactors_lepMVA, paramDefs=binningVariables_nano_noScaleSyst, systName="muLoose"), "el": get_scalefactor("lepton", "Electron_RecoToLoose", sfLib=scalefactors_lepMVA, paramDefs=binningVariables_nano_noScaleSyst, systName="elLoose") } sf_tight = { "mu": get_scalefactor("lepton", "Muon_LooseToTight", sfLib=scalefactors_lepMVA, paramDefs=binningVariables_nano_noScaleSyst, systName="muTight"), "el": get_scalefactor("lepton", "Electron_LooseToTight", sfLib=scalefactors_lepMVA, paramDefs=binningVariables_nano_noScaleSyst, systName="elTight") } nGoodLeptons = op.rng_len(goodLeptons["el"])+op.rng_len(goodLeptons["mu"]) hasTwoGoodLeptons = noSel.refine("has2Lep", cut=(nGoodLeptons > 1)) # avoid overlap with 1l jets = op.sort(op.select(t.Jet, lambda j : op.AND( j.pt > 25., ## you decide... op.abs(j.eta) < 2.4, j.jetId & 0x2, ## tight JetID op.AND( ## lepton-jet cross-cleaning op.NOT(op.rng_any(goodLeptons["el"], lambda l : op.deltaR(l.p4, j.p4) < 0.4)), op.NOT(op.rng_any(goodLeptons["mu"], lambda l : op.deltaR(l.p4, j.p4) < 0.4))) )), lambda j : -j.pt) for fl1,fl2 in product(*repeat(goodLeptons.keys(), 2)): dilepSel = lambda l1,l2 : op.AND( l1.charge != l2.charge, (l1.p4+l2.p4).M() > 12. ) if fl1 == fl2: lGood = op.sort(goodLeptons[fl1], lambda l : -l.pt) dilep = op.combine(lGood, N=2, pred=dilepSel) else: l1Good = op.sort(goodLeptons[fl1], lambda l : -l.pt) l2Good = op.sort(goodLeptons[fl2], lambda l : -l.pt) dilep = op.combine((l1Good, l2Good), pred=dilepSel) ll = dilep[0] hasDilep = hasTwoGoodLeptons.refine(f"hasDilep{fl1}{fl2}", cut=(op.rng_len(dilep) > 0, ll[0].pt > 25.), weight=([ sf_loose[fl1](ll[0]), sf_loose[fl2](ll[1]), sf_tight[fl1](ll[0]), sf_tight[fl2](ll[1]) ] if isMC else None)) plots += [ Plot.make1D(f"dilepton_{fl1}{fl2}_Mll", (ll[0].p4+ll[1].p4).M(), hasDilep, EqB(50, 70, 120.), title="Dilepton mass"), ] for il,ifl in enumerate((fl1, fl2)): plots += [ Plot.make1D(f"dilepton_{fl1}{fl2}_L{il:d}PT", ll[il].pt, hasDilep, EqB(50, 0., 100.), title=f"Lepton {il:d} PT"), Plot.make1D(f"dilepton_{fl1}{fl2}_L{il:d}ETA", ll[il].eta, hasDilep, EqB(50, -2.5, 2.5), title=f"Lepton {il:d} ETA"), ] plots += [ Plot.make1D(f"dilepton_{fl1}{fl2}_nJets", op.rng_len(jets), hasDilep, EqB(15, 0, 15.), title="Jet multiplicity"), ] return plots
def defineSkimSelection(self, t, noSel, sample=None, sampleCfg=None): noSel = super(SkimmerNanoHHtobbWWDL, self).prepareObjects(t, noSel, sample, sampleCfg, "DL", forSkimmer=True) # For the Skimmer, SF must not use defineOnFirstUse -> segmentation fault era = sampleCfg['era'] #self.datadrivenContributions = {} # Avoid all data-driven estimates # Initialize varsToKeep dict # varsToKeep = dict() #---------------------------------------------------------------------------------------# # Selections # #---------------------------------------------------------------------------------------# if not self.inclusive_sel: #----- Check arguments -----# lepton_level = [ "Preselected", "Fakeable", "Tight", "FakeExtrapolation" ] # Only one must be in args jet_level = [ "Ak4", "Ak8", "Resolved0Btag", "Resolved1Btag", "Resolved2Btag", "Boosted" ] # Only one must be in args if [ boolean for (level, boolean) in self.args.__dict__.items() if level in lepton_level ].count(True) != 1: raise RuntimeError( "Only one of the lepton arguments must be used, check --help" ) if [ boolean for (level, boolean) in self.args.__dict__.items() if level in jet_level ].count(True) != 1: raise RuntimeError( "Only one of the jet arguments must be used, check --help") if self.args.Channel not in ["ElEl", "MuMu", "ElMu"]: raise RuntimeError( "Channel must be either 'ElEl', 'MuMu' or 'ElMu'") #----- Lepton selection -----# # Args are passed within the self # selLeptonDict = makeDoubleLeptonSelection(self, noSel, use_dd=False) # makeDoubleLeptonSelection returns dict -> value is list of three selections for 3 channels # [0] -> we take the first and only key and value because restricted to one lepton selection selLeptonList = list(selLeptonDict.values())[0] if self.args.Channel == "ElEl": selObj = selLeptonList[ 0] # First item of list is ElEl selection if self.args.Channel == "MuMu": selObj = selLeptonList[ 1] # Second item of list is MuMu selection if self.args.Channel == "ElMu": selObj = selLeptonList[ 2] # Third item of list is ElMu selection #----- Jet selection -----# # Since the selections in one line, we can use the non copy option of the selection to modify the selection object internally if any([ self.args.__dict__[item] for item in ["Ak4", "Resolved0Btag", "Resolved1Btag", "Resolved2Btag"] ]): makeAtLeastTwoAk4JetSelection(self, selObj, use_dd=False) if any([self.args.__dict__[item] for item in ["Ak8", "Boosted"]]): makeAtLeastOneAk8JetSelection(self, selObj, use_dd=False) if self.args.Resolved0Btag: makeExclusiveResolvedNoBtagSelection(self, selObj, use_dd=False) if self.args.Resolved1Btag: makeExclusiveResolvedOneBtagSelection(self, selObj, use_dd=False) if self.args.Resolved2Btag: makeExclusiveResolvedTwoBtagsSelection(self, selObj, use_dd=False) if self.args.Boosted: makeInclusiveBoostedSelection(self, selObj, use_dd=False) #---------------------------------------------------------------------------------------# # Synchronization tree # #---------------------------------------------------------------------------------------# if self.args.Synchronization: # Event variables # varsToKeep["event"] = None # Already in tree varsToKeep["run"] = None # Already in tree varsToKeep["ls"] = t.luminosityBlock varsToKeep["n_presel_mu"] = op.static_cast( "UInt_t", op.rng_len(self.muonsPreSel)) varsToKeep["n_fakeablesel_mu"] = op.static_cast( "UInt_t", op.rng_len(self.muonsFakeSel)) varsToKeep["n_mvasel_mu"] = op.static_cast( "UInt_t", op.rng_len(self.muonsTightSel)) varsToKeep["n_presel_ele"] = op.static_cast( "UInt_t", op.rng_len(self.electronsPreSel)) varsToKeep["n_fakeablesel_ele"] = op.static_cast( "UInt_t", op.rng_len(self.electronsFakeSel)) varsToKeep["n_mvasel_ele"] = op.static_cast( "UInt_t", op.rng_len(self.electronsTightSel)) varsToKeep["n_presel_ak4Jet"] = op.static_cast( "UInt_t", op.rng_len(self.ak4Jets)) varsToKeep["n_presel_ak8Jet"] = op.static_cast( "UInt_t", op.rng_len(self.ak8BJets)) varsToKeep["n_medium_ak4BJet"] = op.static_cast( "UInt_t", op.rng_len(self.ak4BJets)) varsToKeep["is_SR"] = op.static_cast( "UInt_t", op.OR( op.rng_len(self.ElElDileptonTightSel) >= 1, op.rng_len(self.MuMuDileptonTightSel) >= 1, op.rng_len(self.ElMuDileptonTightSel) >= 1)) varsToKeep["is_CR"] = op.static_cast( "UInt_t", op.OR( op.rng_len(self.ElElDileptonFakeExtrapolationSel) >= 1, op.rng_len(self.MuMuDileptonFakeExtrapolationSel) >= 1, op.rng_len(self.ElMuDileptonFakeExtrapolationSel) >= 1)) varsToKeep["is_ee"] = op.static_cast( "UInt_t", op.OR( op.rng_len(self.ElElDileptonTightSel) >= 1, op.rng_len(self.ElElDileptonFakeExtrapolationSel) >= 1)) varsToKeep["is_mm"] = op.static_cast( "UInt_t", op.OR( op.rng_len(self.MuMuDileptonTightSel) >= 1, op.rng_len(self.MuMuDileptonFakeExtrapolationSel) >= 1)) varsToKeep["is_em"] = op.static_cast( "UInt_t", op.OR( op.rng_len(self.ElMuDileptonTightSel) >= 1, op.rng_len(self.ElMuDileptonFakeExtrapolationSel) >= 1)) varsToKeep["is_resolved"] = op.switch( op.AND( op.rng_len(self.ak4Jets) >= 2, op.rng_len(self.ak4BJets) >= 1, op.rng_len(self.ak8BJets) == 0), op.c_bool(True), op.c_bool(False)) varsToKeep["is_boosted"] = op.switch( op.rng_len(self.ak8BJets) >= 1, op.c_bool(True), op.c_bool(False)) # Triggers # varsToKeep['n_leadfakeableSel_ele'] = op.static_cast( "UInt_t", op.rng_len(self.leadElectronsFakeSel)) varsToKeep['n_leadfakeableSel_mu'] = op.static_cast( "UInt_t", op.rng_len(self.leadMuonsFakeSel)) varsToKeep["triggers"] = self.triggers varsToKeep["triggers_SingleElectron"] = op.OR( *self.triggersPerPrimaryDataset['SingleElectron']) varsToKeep["triggers_SingleMuon"] = op.OR( *self.triggersPerPrimaryDataset['SingleMuon']) varsToKeep["triggers_DoubleElectron"] = op.OR( *self.triggersPerPrimaryDataset['DoubleEGamma']) varsToKeep["triggers_DoubleMuon"] = op.OR( *self.triggersPerPrimaryDataset['DoubleMuon']) varsToKeep["triggers_MuonElectron"] = op.OR( *self.triggersPerPrimaryDataset['MuonEG']) # Muons # for i in range(1, 3): # 2 leading muons varsToKeep["mu{}_pt".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].pt, op.c_float(-9999., "float")) varsToKeep["mu{}_eta".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].eta, op.c_float(-9999.)) varsToKeep["mu{}_phi".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].phi, op.c_float(-9999.)) varsToKeep["mu{}_E".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].p4.E(), op.c_float(-9999., "float")) varsToKeep["mu{}_charge".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].charge, op.c_int(-9999.)) varsToKeep["mu{}_conept".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muon_conept[self.muonsPreSel[i - 1].idx], op.c_float(-9999.)) varsToKeep["mu{}_miniRelIso".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].miniPFRelIso_all, op.c_float(-9999.)) varsToKeep["mu{}_PFRelIso04".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].pfRelIso04_all, op.c_float(-9999.)) varsToKeep["mu{}_jetNDauChargedMVASel".format(i)] = op.c_float( -9999.) varsToKeep["mu{}_jetPtRel".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].jetPtRelv2, op.c_float(-9999.)) varsToKeep["mu{}_jetRelIso".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].jetRelIso, op.c_float(-9999.)) varsToKeep["mu{}_jetDeepJet".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].jet.btagDeepFlavB, op.c_float(-9999.)) varsToKeep["mu{}_sip3D".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].sip3d, op.c_float(-9999.)) varsToKeep["mu{}_dxy".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].dxy, op.c_float(-9999.)) varsToKeep["mu{}_dxyAbs".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, op.abs(self.muonsPreSel[i - 1].dxy), op.c_float(-9999.)) varsToKeep["mu{}_dz".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].dz, op.c_float(-9999.)) varsToKeep["mu{}_segmentCompatibility".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].segmentComp, op.c_float(-9999.)) varsToKeep["mu{}_leptonMVA".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].mvaTTH, op.c_float(-9999.)) varsToKeep["mu{}_mediumID".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].mediumId, op.c_float(-9999., "Bool_t")) varsToKeep["mu{}_dpt_div_pt".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].tunepRelPt, op.c_float(-9999.)) # Not sure varsToKeep["mu{}_isfakeablesel".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, op.switch(self.lambda_muonFakeSel(self.muonsPreSel[i - 1]), op.c_int(1), op.c_int(0)), op.c_int(-9999)) varsToKeep["mu{}_ismvasel".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, op.switch( op.AND( self.lambda_muonTightSel(self.muonsPreSel[i - 1]), self.lambda_muonFakeSel(self.muonsPreSel[i - 1])), op.c_int(1), op.c_int(0)), op.c_int(-9999)) # mvasel encompasses fakeablesel varsToKeep["mu{}_isGenMatched".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, op.switch(self.lambda_is_matched(self.muonsPreSel[i - 1]), op.c_int(1), op.c_int(0)), op.c_int(-9999)) varsToKeep["mu{}_genPartFlav".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonsPreSel[i - 1].genPartFlav, op.c_int(-9999)) varsToKeep["mu{}_FR".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.muonFR(self.muonsPreSel[i - 1]), op.c_int(-9999)) varsToKeep["mu{}_FRCorr".format(i)] = op.switch( op.rng_len(self.muonsPreSel) >= i, self.lambda_FF_mu(self.muonsPreSel[i - 1]), op.c_int(-9999)) # Electrons # for i in range(1, 3): # 2 leading electrons varsToKeep["ele{}_pt".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].pt, op.c_float(-9999.)) varsToKeep["ele{}_eta".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].eta, op.c_float(-9999.)) varsToKeep["ele{}_phi".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].phi, op.c_float(-9999.)) varsToKeep["ele{}_E".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].p4.E(), op.c_float(-9999., "float")) varsToKeep["ele{}_charge".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].charge, op.c_int(-9999.)) varsToKeep["ele{}_conept".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electron_conept[self.electronsPreSel[i - 1].idx], op.c_float(-9999.)) varsToKeep["ele{}_miniRelIso".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].miniPFRelIso_all, op.c_float(-9999.)) varsToKeep["ele{}_PFRelIso03".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].pfRelIso03_all, op.c_float(-9999.)) # Iso03, Iso04 not in NanoAOD varsToKeep["ele{}_jetNDauChargedMVASel".format( i)] = op.c_float(-9999.) varsToKeep["ele{}_jetPtRel".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].jetPtRelv2, op.c_float(-9999.)) varsToKeep["ele{}_jetRelIso".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].jetRelIso, op.c_float(-9999.)) varsToKeep["ele{}_jetDeepJet".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].jet.btagDeepFlavB, op.c_float(-9999.)) varsToKeep["ele{}_sip3D".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].sip3d, op.c_float(-9999.)) varsToKeep["ele{}_dxy".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].dxy, op.c_float(-9999.)) varsToKeep["ele{}_dxyAbs".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, op.abs(self.electronsPreSel[i - 1].dxy), op.c_float(-9999.)) varsToKeep["ele{}_dz".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].dz, op.c_float(-9999.)) varsToKeep["ele{}_ntMVAeleID".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].mvaFall17V2noIso, op.c_float(-9999.)) varsToKeep["ele{}_leptonMVA".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].mvaTTH, op.c_float(-9999.)) varsToKeep["ele{}_passesConversionVeto".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].convVeto, op.c_float(-9999., "Bool_t")) varsToKeep["ele{}_nMissingHits".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].lostHits, op.c_float(-9999., "UChar_t")) varsToKeep["ele{}_sigmaEtaEta".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].sieie, op.c_float(-9999.)) varsToKeep["ele{}_HoE".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].hoe, op.c_float(-9999.)) varsToKeep["ele{}_OoEminusOoP".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].eInvMinusPInv, op.c_float(-9999.)) varsToKeep["ele{}_isfakeablesel".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, op.switch( self.lambda_electronFakeSel(self.electronsPreSel[i - 1]), op.c_int(1), op.c_int(0)), op.c_int(-9999)) varsToKeep["ele{}_ismvasel".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, op.switch( op.AND( self.lambda_electronTightSel( self.electronsPreSel[i - 1]), self.lambda_electronFakeSel( self.electronsPreSel[i - 1])), op.c_int(1), op.c_int(0)), op.c_int(-9999)) # mvasel encompasses fakeablesel varsToKeep["ele{}_isGenMatched".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, op.switch( self.lambda_is_matched(self.electronsPreSel[i - 1]), op.c_int(1), op.c_int(0)), op.c_int(-9999)) varsToKeep["ele{}_genPartFlav".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].genPartFlav, op.c_int(-9999)) varsToKeep["ele{}_deltaEtaSC".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronsPreSel[i - 1].deltaEtaSC, op.c_int(-9999)) varsToKeep["ele{}_FR".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.electronFR(self.electronsPreSel[i - 1]), op.c_int(-9999)) varsToKeep["ele{}_FF".format(i)] = op.switch( op.rng_len(self.electronsPreSel) >= i, self.lambda_FF_el(self.electronsPreSel[i - 1]), op.c_int(-9999)) # AK4 Jets # for i in range(1, 5): # 4 leading jets varsToKeep["ak4Jet{}_pt".format(i)] = op.switch( op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].pt, op.c_float(-9999., "float")) varsToKeep["ak4Jet{}_eta".format(i)] = op.switch( op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].eta, op.c_float(-9999.)) varsToKeep["ak4Jet{}_phi".format(i)] = op.switch( op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].phi, op.c_float(-9999.)) varsToKeep["ak4Jet{}_E".format(i)] = op.switch( op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].p4.E(), op.c_float(-9999., "float")) varsToKeep["ak4Jet{}_CSV".format(i)] = op.switch( op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].btagDeepFlavB, op.c_float(-9999.)) varsToKeep["ak4Jet{}_hadronFlavour".format(i)] = op.switch( op.rng_len(self.ak4Jets) >= i, self.ak4Jets[i - 1].hadronFlavour, op.c_float(-9999.)) varsToKeep["ak4Jet{}_btagSF".format(i)] = op.switch( op.rng_len(self.ak4Jets) >= i, self.DeepJetDiscReshapingSF(self.ak4Jets[i - 1]), op.c_float(-9999.)) # AK8 Jets # for i in range(1, 3): # 2 leading fatjets varsToKeep["ak8Jet{}_pt".format(i)] = op.switch( op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].pt, op.c_float(-9999.)) varsToKeep["ak8Jet{}_eta".format(i)] = op.switch( op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].eta, op.c_float(-9999.)) varsToKeep["ak8Jet{}_phi".format(i)] = op.switch( op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].phi, op.c_float(-9999.)) varsToKeep["ak8Jet{}_E".format(i)] = op.switch( op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].p4.E(), op.c_float(-9999., "float")) varsToKeep["ak8Jet{}_msoftdrop".format(i)] = op.switch( op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].msoftdrop, op.c_float(-9999.)) varsToKeep["ak8Jet{}_tau1".format(i)] = op.switch( op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].tau1, op.c_float(-9999.)) varsToKeep["ak8Jet{}_tau2".format(i)] = op.switch( op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].tau2, op.c_float(-9999.)) varsToKeep["ak8Jet{}_subjet0_pt".format(i)] = op.switch( op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].subJet1.pt, op.c_float(-9999.)) varsToKeep["ak8Jet{}_subjet0_eta".format(i)] = op.switch( op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].subJet1.eta, op.c_float(-9999.)) varsToKeep["ak8Jet{}_subjet0_phi".format(i)] = op.switch( op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].subJet1.phi, op.c_float(-9999.)) varsToKeep["ak8Jet{}_subjet0_CSV".format(i)] = op.switch( op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].subJet1.btagDeepB, op.c_float(-9999.)) varsToKeep["ak8Jet{}_subjet1_pt".format(i)] = op.switch( op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].subJet2.pt, op.c_float(-9999.)) varsToKeep["ak8Jet{}_subjet1_eta".format(i)] = op.switch( op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].subJet2.eta, op.c_float(-9999.)) varsToKeep["ak8Jet{}_subjet1_phi".format(i)] = op.switch( op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].subJet2.phi, op.c_float(-9999.)) varsToKeep["ak8Jet{}_subjet1_CSV".format(i)] = op.switch( op.rng_len(self.ak8BJets) >= i, self.ak8BJets[i - 1].subJet2.btagDeepB, op.c_float(-9999.)) # MET # varsToKeep["PFMET"] = self.corrMET.pt varsToKeep["PFMETphi"] = self.corrMET.phi # HME # # SF # from operator import mul from functools import reduce electronMuon_cont = op.combine( (self.electronsFakeSel, self.muonsFakeSel)) varsToKeep["trigger_SF"] = op.multiSwitch( (op.AND( op.rng_len(self.electronsTightSel) == 1, op.rng_len(self.muonsTightSel) == 0), self.ttH_singleElectron_trigSF(self.electronsTightSel[0])), (op.AND( op.rng_len(self.electronsTightSel) == 0, op.rng_len(self.muonsTightSel) == 1), self.ttH_singleMuon_trigSF(self.muonsTightSel[0])), (op.AND( op.rng_len(self.electronsTightSel) >= 2, op.rng_len(self.muonsTightSel) == 0), self.lambda_ttH_doubleElectron_trigSF( self.electronsTightSel)), (op.AND( op.rng_len(self.electronsTightSel) == 0, op.rng_len(self.muonsTightSel) >= 2), self.lambda_ttH_doubleMuon_trigSF(self.muonsTightSel)), (op.AND( op.rng_len(self.electronsTightSel) >= 1, op.rng_len(self.muonsTightSel) >= 1), self.lambda_ttH_electronMuon_trigSF(electronMuon_cont[0])), op.c_float(1.)) varsToKeep["lepton_IDSF"] = op.rng_product(self.electronsTightSel, lambda el : reduce(mul,self.lambda_ElectronLooseSF(el)+self.lambda_ElectronTightSF(el))) * \ op.rng_product(self.muonsTightSel, lambda mu : reduce(mul,self.lambda_MuonLooseSF(mu)+self.lambda_MuonTightSF(mu))) varsToKeep["lepton_IDSF_recoToLoose"] = op.rng_product(self.electronsTightSel, lambda el : reduce(mul,self.lambda_ElectronLooseSF(el))) * \ op.rng_product(self.muonsTightSel, lambda mu : reduce(mul,self.lambda_MuonLooseSF(mu))) varsToKeep["lepton_IDSF_looseToTight"] = op.rng_product(self.electronsTightSel, lambda el : reduce(mul,self.lambda_ElectronTightSF(el))) * \ op.rng_product(self.muonsTightSel, lambda mu : reduce(mul,self.lambda_MuonTightSF(mu))) # L1 Prefire # if era in ["2016", "2017"]: varsToKeep["L1prefire"] = self.L1Prefiring else: varsToKeep["L1prefire"] = op.c_float(-9999.) # Fake rate # if self.args.FakeExtrapolation: varsToKeep["fakeRate"] = op.multiSwitch( (op.rng_len(self.ElElDileptonFakeExtrapolationSel) >= 1, self.ElElFakeFactor( self.ElElDileptonFakeExtrapolationSel[0])), (op.rng_len(self.MuMuDileptonFakeExtrapolationSel) >= 1, self.MuMuFakeFactor( self.MuMuDileptonFakeExtrapolationSel[0])), (op.rng_len(self.ElMuDileptonFakeExtrapolationSel) >= 1, self.ElMuFakeFactor( self.ElMuDileptonFakeExtrapolationSel[0])), op.c_float(0.)) else: varsToKeep["fakeRate"] = op.c_float(-9999.) # Btagging SF # varsToKeep["btag_SF"] = self.btagSF if "BtagRatioWeight" in self.__dict__.keys(): varsToKeep["btag_reweighting"] = self.BtagRatioWeight varsToKeep[ "btag_reweighting_SF"] = self.btagSF * self.BtagRatioWeight # ttbar PT reweighting # if "group" in sampleCfg and sampleCfg["group"] == 'ttbar': varsToKeep["topPt_wgt"] = self.ttbar_weight( self.genTop[0], self.genAntitop[0]) # Event Weight # if self.is_MC: #varsToKeep["MC_weight"] = op.sign(t.genWeight) varsToKeep["MC_weight"] = t.genWeight puWeightsFile = os.path.join(os.path.dirname(__file__), "data", "pileup", sampleCfg["pufile"]) varsToKeep["PU_weight"] = makePileupWeight( puWeightsFile, t.Pileup_nTrueInt, nameHint=f"puweightFromFile{sample}".replace('-', '_')) varsToKeep[ "eventWeight"] = noSel.weight if self.inclusive_sel else selObj.sel.weight if self.inclusive_sel: return noSel, varsToKeep else: return selObj.sel, varsToKeep #---------------------------------------------------------------------------------------# # Selection tree # #---------------------------------------------------------------------------------------# #----- MET variables -----# MET = self.corrMET varsToKeep['MET_pt'] = MET.pt varsToKeep['MET_phi'] = MET.phi #----- Lepton variables -----# if self.args.Channel is None: raise RuntimeError("You need to specify --Channel") dilepton = None if self.args.Preselected: if self.args.Channel == "ElEl": dilepton = self.ElElDileptonPreSel[0] if self.args.Channel == "MuMu": dilepton = self.MuMuDileptonPreSel[0] if self.args.Channel == "ElMu": dilepton = self.ElMuDileptonPreSel[0] if self.args.Fakeable: if self.args.Channel == "ElEl": dilepton = self.ElElDileptonFakeSel[0] if self.args.Channel == "MuMu": dilepton = self.MuMuDileptonFakeSel[0] if self.args.Channel == "ElMu": dilepton = self.ElMuDileptonFakeSel[0] if self.args.Tight: if self.args.Channel == "ElEl": dilepton = self.ElElDileptonTightSel[0] if self.args.Channel == "MuMu": dilepton = self.MuMuDileptonTightSel[0] if self.args.Channel == "ElMu": dilepton = self.ElMuDileptonTightSel[0] if self.args.FakeExtrapolation: if self.args.Channel == "ElEl": dilepton = self.ElElDileptonFakeExtrapolationSel[0] if self.args.Channel == "MuMu": dilepton = self.MuMuDileptonFakeExtrapolationSel[0] if self.args.Channel == "ElMu": dilepton = self.ElMuDileptonFakeExtrapolationSel[0] varsToKeep['l1_Px'] = dilepton[0].p4.Px() varsToKeep['l1_Py'] = dilepton[0].p4.Py() varsToKeep['l1_Pz'] = dilepton[0].p4.Pz() varsToKeep['l1_E'] = dilepton[0].p4.E() varsToKeep['l1_pt'] = dilepton[0].pt varsToKeep['l1_eta'] = dilepton[0].eta varsToKeep['l1_phi'] = dilepton[0].phi varsToKeep['l2_Px'] = dilepton[1].p4.Px() varsToKeep['l2_Py'] = dilepton[1].p4.Py() varsToKeep['l2_Pz'] = dilepton[1].p4.Pz() varsToKeep['l2_E'] = dilepton[1].p4.E() varsToKeep['l2_pt'] = dilepton[1].pt varsToKeep['l2_eta'] = dilepton[1].eta varsToKeep['l2_phi'] = dilepton[1].phi varsToKeep['ll_pt'] = (dilepton[0].p4 + dilepton[1].p4).Pt() varsToKeep['ll_DR'] = op.deltaR(dilepton[0].p4, dilepton[1].p4) varsToKeep['ll_DPhi'] = op.deltaPhi(dilepton[0].p4, dilepton[1].p4) # Might need abs varsToKeep['llmet_DPhi'] = self.HLL.DilepMET_deltaPhi( dilepton[0], dilepton[1], MET) varsToKeep['llmet_pt'] = self.HLL.DilepMET_Pt(dilepton[0], dilepton[1], MET) varsToKeep['ll_M'] = op.invariant_mass(dilepton[0].p4, dilepton[1].p4) varsToKeep['ll_MT'] = self.HLL.MT_ll(dilepton[0], dilepton[1], MET) #----- Jet variables -----# if any([ self.args.__dict__[item] for item in ["Ak4", "Resolved0Btag", "Resolved1Btag", "Resolved2Btag"] ]): if self.args.Ak4: leadjet = self.ak4Jets[0] subleadjet = self.ak4Jets[1] if self.args.Resolved0Btag: leadjet = self.ak4LightJetsByBtagScore[0] subleadjet = self.ak4LightJetsByBtagScore[0] if self.args.Resolved1Btag: leadjet = self.ak4BJets[0] subleadjet = self.ak4LightJetsByBtagScore[0] if self.args.Resolved2Btag: leadjet = self.ak4BJets[0] subleadjet = self.ak4BJets[1] varsToKeep['j1_Px'] = leadjet.p4.Px() varsToKeep['j1_Py'] = leadjet.p4.Py() varsToKeep['j1_Pz'] = leadjet.p4.Pz() varsToKeep['j1_E'] = leadjet.p4.E() varsToKeep['j1_pt'] = leadjet.pt varsToKeep['j1_eta'] = leadjet.eta varsToKeep['j1_phi'] = leadjet.phi varsToKeep['j2_Px'] = subleadjet.p4.Px() varsToKeep['j2_Py'] = subleadjet.p4.Py() varsToKeep['j2_Pz'] = subleadjet.p4.Pz() varsToKeep['j2_E'] = subleadjet.p4.E() varsToKeep['j2_pt'] = subleadjet.pt varsToKeep['j2_eta'] = subleadjet.eta varsToKeep['j2_phi'] = subleadjet.phi varsToKeep['jj_pt'] = (leadjet.p4 + subleadjet.p4).Pt() varsToKeep['jj_DR'] = op.deltaR(leadjet.p4, subleadjet.p4) varsToKeep['jj_DPhi'] = op.deltaPhi( leadjet.p4, subleadjet.p4) # Might need abs varsToKeep['jj_M'] = op.invariant_mass(leadjet.p4, subleadjet.p4) varsToKeep['lljj_M'] = self.HLL.M_lljj(dilepton[0], dilepton[1], leadjet, subleadjet) varsToKeep['lljj_MT'] = self.HLL.MT_lljj(dilepton[0], dilepton[1], leadjet, subleadjet, MET) varsToKeep['lj_MinDR'] = self.HLL.MinDR_lj(dilepton[0], dilepton[1], leadjet, subleadjet) varsToKeep['HT2'] = self.HLL.HT2(dilepton[0], dilepton[1], leadjet, subleadjet, MET) varsToKeep['HT2R'] = self.HLL.HT2R(dilepton[0], dilepton[1], leadjet, subleadjet, MET) #----- Fatjet variables -----# if any([self.args.__dict__[item] for item in ["Ak8", "Boosted"]]): if self.args.Ak8: fatjet = self.ak8Jets[0] if self.args.Boosted: fatjet = self.ak8BJets[0] varsToKeep['fatjet_Px'] = fatjet.p4.Px() varsToKeep['fatjet_Py'] = fatjet.p4.Py() varsToKeep['fatjet_Pz'] = fatjet.p4.Pz() varsToKeep['fatjet_E'] = fatjet.p4.E() varsToKeep['fatjet_pt'] = fatjet.pt varsToKeep['fatjet_eta'] = fatjet.eta varsToKeep['fatjet_phi'] = fatjet.phi varsToKeep['fatjet_softdropMass'] = fatjet.msoftdrop varsToKeep['lljj_M'] = self.HLL.M_lljj(dilepton[0], dilepton[1], fatjet.subJet1, fatjet.subJet2) varsToKeep['lljj_MT'] = self.HLL.MT_lljj(dilepton[0], dilepton[1], fatjet.subJet1, fatjet.subJet2, MET) varsToKeep['lj_MinDR'] = self.HLL.MinDR_lj(dilepton[0], dilepton[1], fatjet.subJet1, fatjet.subJet2) varsToKeep['HT2'] = self.HLL.HT2(dilepton[0], dilepton[1], fatjet.subJet1, fatjet.subJet2, MET) varsToKeep['HT2R'] = self.HLL.HT2R(dilepton[0], dilepton[1], fatjet.subJet1, fatjet.subJet2, MET) #----- Additional variables -----# varsToKeep["MC_weight"] = t.genWeight varsToKeep['total_weight'] = selObj.sel.weight #return leptonSel.sel, varsToKeep return selObj.sel, varsToKeep
def definePlots(self, t, noSel, sample=None, sampleCfg=None): from bamboo.plots import Plot, CutFlowReport, SummedPlot from bamboo.plots import EquidistantBinning as EqB from bamboo import treefunctions as op isMC = self.isMC(sample) if sampleCfg.get("alt-syst"): noSel = noSel.refine("withoutsyst", autoSyst=False) plots = [] trigCut, trigWeight = None, None if isMC: muR = op.systematic(op.c_float(1.), name="muR", up=t.PSWeight[2], down=t.PSWeight[0]) muF = op.systematic(op.c_float(1.), name="muF", up=t.PSWeight[3], down=t.PSWeight[1]) noSel = noSel.refine( "mcWeight", weight=[t.genWeight, t.puWeight, t.PrefireWeight, muR, muF]) trigCut = op.OR(t.HLT.HIEle20_Ele12_CaloIdL_TrackIdL_IsoVL_DZ, t.HLT.HIL3DoubleMu0, t.HLT.HIL3Mu20, t.HLT.HIEle20_WPLoose_Gsf) trigWeight = op.switch( op.OR(t.HLT.HIEle20_Ele12_CaloIdL_TrackIdL_IsoVL_DZ, t.HLT.HIL3DoubleMu0), op.c_float(1.), op.switch(t.HLT.HIL3Mu20, op.c_float(306.913 / 308.545), op.c_float(264.410 / 308.545)) ) ## FIXME these are wrong - you will get the final values from team A else: ## trigger order: dielectron, dimuon or single muon, single electron pd = sample.split("_")[0] if pd == "SingleMuon": trigCut = op.AND( op.NOT(t.HLT.HIEle20_Ele12_CaloIdL_TrackIdL_IsoVL_DZ), op.OR(t.HLT.HIL3DoubleMu0, t.HLT.HIL3Mu20)) elif pd == "HighEGJet": trigCut = op.OR( t.HLT.HIEle20_Ele12_CaloIdL_TrackIdL_IsoVL_DZ, op.AND(op.NOT(op.OR(t.HLT.HIL3DoubleMu0, t.HLT.HIL3Mu20)), t.HLT.HIEle20_WPLoose_Gsf)) noSel = noSel.refine("trig", cut=trigCut, weight=trigWeight) #plots += [Plot.make1D("nTotalEvents", op.rng_len([1]), noSel , EqB(1, 0, 1.), title="nTotalEvents")] plots.append( Plot.make1D("nTotalJets", op.rng_len(t.Jet), noSel, EqB(15, 0, 15.), title="Initial Jet multiplicity")) #noSel = noSel.refine("trig", cut=op.OR(t.HLT.HIL3DoubleMu0, t.HLT.HIEle20_Ele12_CaloIdL_TrackIdL_IsoVL_DZ)) # plots = [] goodLeptons = { "el": op.select( t.Electron, lambda el: op.AND(el.pt > 15., op.abs(el.p4.Eta()) < 2.5) ), # op.select(t.Electron, partial(isGoodElectron, ptCut=15.)), "mu": op.select(t.Muon, lambda mu: mu.pt > 20. ) # op.select(t.Muon, partial(isGoodMuon, ptCut=15.)) } plots += [ Plot.make1D( "trig_nLeptons15", op.rng_len(goodLeptons["el"]) + op.rng_len(goodLeptons["mu"]), noSel, EqB(15, 0., 15.)), Plot.make1D("trig_nEl15", op.rng_len(goodLeptons["el"]), noSel, EqB(15, 0., 15.)), Plot.make1D("trig_nMu15", op.rng_len(goodLeptons["mu"]), noSel, EqB(15, 0., 15.)) ] from bamboo.scalefactors import get_scalefactor sf_loose = { "mu": get_scalefactor("lepton", "Muon_RecoToLoose", sfLib=scalefactors_lepMVA, paramDefs=binningVariables_nano_noScaleSyst, systName="muLoose"), "el": get_scalefactor("lepton", "Electron_RecoToLoose", sfLib=scalefactors_lepMVA, paramDefs=binningVariables_nano_noScaleSyst, systName="elLoose") } sf_tight = { "mu": get_scalefactor("lepton", "Muon_LooseToTight", sfLib=scalefactors_lepMVA, paramDefs=binningVariables_nano_noScaleSyst, systName="muTight"), "el": get_scalefactor("lepton", "Electron_LooseToTight", sfLib=scalefactors_lepMVA, paramDefs=binningVariables_nano_noScaleSyst, systName="elTight") } nGoodLeptons = op.rng_len(goodLeptons["el"]) + op.rng_len( goodLeptons["mu"]) hasTwoGoodLeptons = noSel.refine( "has2Lep", cut=(nGoodLeptons > 1)) # avoid overlap with 1l jets = op.sort( op.select( t.Jet, lambda j: op.AND( j.pt > 25., op.abs(j.eta) < 2.4, j.jetId & 0x2, op.AND( op.NOT( op.rng_any(goodLeptons["el"], lambda l: op.deltaR( l.p4, j.p4) < 0.4)), op.NOT( op.rng_any(goodLeptons["mu"], lambda l: op.deltaR( l.p4, j.p4) < 0.4))))), lambda j: -j.pt) ## WP: see https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation94X loosebjets = op.select(jets, lambda j: j.btagDeepB > 0.1522) mediumbjets = op.select(jets, lambda j: j.btagDeepB > 0.4941) for fl1, fl2 in product(*repeat(goodLeptons.keys(), 2)): dilepSel = lambda l1, l2: op.AND(l1.charge != l2.charge, (l1.p4 + l2.p4).M() > 12.) if fl1 == fl2: lGood = op.sort(goodLeptons[fl1], lambda l: -l.pt) dilep = op.combine(lGood, N=2, pred=dilepSel) else: l1Good = op.sort(goodLeptons[fl1], lambda l: -l.pt) l2Good = op.sort(goodLeptons[fl2], lambda l: -l.pt) dilep = op.combine((l1Good, l2Good), pred=dilepSel) ll = dilep[0] hasDilep = hasTwoGoodLeptons.refine( f"hasDilep{fl1}{fl2}", cut=(op.rng_len(dilep) > 0, ll[0].pt > 25.), weight=([ sf_loose[fl1](ll[0]), sf_loose[fl2](ll[1]), sf_tight[fl1]( ll[0]), sf_tight[fl2](ll[1]) ] if isMC else None)) plots += [ Plot.make1D(f"dilepton_{fl1}{fl2}_Mll", (ll[0].p4 + ll[1].p4).M(), hasDilep, EqB(50, 70, 120.), title="Dilepton mass"), ] for il, ifl in enumerate((fl1, fl2)): plots += [ Plot.make1D(f"dilepton_{fl1}{fl2}_L{il:d}PT", ll[il].pt, hasDilep, EqB(50, 0., 100.), title=f"Lepton {il:d} PT"), Plot.make1D(f"dilepton_{fl1}{fl2}_L{il:d}ETA", ll[il].eta, hasDilep, EqB(50, -2.5, 2.5), title=f"Lepton {il:d} ETA"), ] plots += [ Plot.make1D(f"dilepton_{fl1}{fl2}_nJets", op.rng_len(jets), hasDilep, EqB(15, 0, 15.), title="Jet multiplicity"), Plot.make1D(f"dilepton_{fl1}{fl2}_nLooseBJets", op.rng_len(loosebjets), hasDilep, EqB(15, 0, 15.), title="Loose b-jet multiplicity"), Plot.make1D(f"dilepton_{fl1}{fl2}_nMediumBJets", op.rng_len(mediumbjets), hasDilep, EqB(15, 0, 15.), title="Medium b-jet multiplicity"), #Plot.make1D(f"dilepton_{fl1}{fl2}_nSelectedEvents", 1, hasDilep, EqB(1, 0, 1.), title="nSelectedEvents") ] #muons = op.select(t.Muon, lambda mu : mu.pt > 20.) #twoMuSel = noSel.refine("twoMuons", cut=[ op.rng_len(muons) > 1 ]) #electrons = op.select(t.Electron, lambda el : op.AND(el.pt > 15. , op.abs(el.p4.Eta()) < 2.5)) #twoElSel = noSel.refine("twoElectrons", cut=[ op.rng_len(electrons) > 1 ]) #oselmu = op.combine((electrons, muons)) #leptons = oselmu[0] #twoLepSel = noSel.refine("twoLeptons", cut=[ op.rng_len(electrons) == 1 , op.rng_len(muons) == 1 ]) #jets = op.select(t.Jet, lambda j : j.pt > 30.) #bjets = op.select(jets, lambda j : j.btagDeepFlavB > 0.2217) #plots.append(Plot.make1D("dimu_M", # op.invariant_mass(muons[0].p4, muons[1].p4), twoMuSel, EqB(100, 20., 120.), # title="Dimuon invariant mass", plotopts={"show-overflow":False, # "legend-position": [0.2, 0.6, 0.5, 0.9]})) #plots.append(Plot.make1D("diel_M", # op.invariant_mass(electrons[0].p4, electrons[1].p4), twoElSel, EqB(100, 20., 120.), # title="Dielectron invariant mass", plotopts={"show-overflow":False, # "legend-position": [0.2, 0.6, 0.5, 0.9]})) #plots.append(Plot.make1D("dilep_M", # op.invariant_mass(leptons[0].p4, leptons[1].p4) , twoLepSel, EqB(100, 20., 120.), # title="Dimuon invariant mass", plotopts={"show-overflow":False, # "legend-position": [0.2, 0.6, 0.5, 0.9]})) #plots.append(SummedPlot("Mjj", plots, title="m(jj)")) #plots.append(Plot.make1D("nJets_dimu",op.rng_len(jets), twoMuSel, EqB(10, -0.5, 9.5), # title="Jet multiplicity", plotopts={"show-overflow":False, # "legend-position": [0.2, 0.6, 0.5, 0.9]})) #plots.append(Plot.make1D("nBJets_dimu",op.rng_len(bjets), twoMuSel, EqB(10, -0.5, 9.5), # title="Jet multiplicity", plotopts={"show-overflow":False, # "legend-position": [0.2, 0.6, 0.5, 0.9]})) #plots.append(Plot.make1D("nJets_diel",op.rng_len(jets), twoElSel, EqB(10, -0.5, 9.5), # title="Jet multiplicity", plotopts={"show-overflow":False, # "legend-position": [0.2, 0.6, 0.5, 0.9]})) #plots.append(Plot.make1D("nBJets_diel",op.rng_len(bjets), twoElSel, EqB(10, -0.5, 9.5), # title="Jet multiplicity", plotopts={"show-overflow":False, # "legend-position": [0.2, 0.6, 0.5, 0.9]})) #plots.append(Plot.make1D("nJets_elmu",op.rng_len(jets), twoLepSel, EqB(10, -0.5, 9.5), # title="Jet multiplicity", plotopts={"show-overflow":False, # "legend-position": [0.2, 0.6, 0.5, 0.9]})) #plots.append(Plot.make1D("nBJets_elmu",op.rng_len(bjets), twoLepSel, EqB(10, -0.5, 9.5), # title="Jet multiplicity", plotopts={"show-overflow":False, # "legend-position": [0.2, 0.6, 0.5, 0.9]})) return plots
def definePlots(self, t, noSel, sample=None, sampleCfg=None): from bamboo.plots import CutFlowReport, SummedPlot from bamboo.plots import EquidistantBinning as EqB from bamboo import treefunctions as op isMC = self.isMC(sample) trigCut, trigWeight = None, None if isMC: trigCut = op.OR(t.HLT.HIEle20_Ele12_CaloIdL_TrackIdL_IsoVL_DZ, t.HLT.HIL3DoubleMu0, t.HLT.HIL3Mu20, t.HLT.HIEle20_WPLoose_Gsf) trigWeight = op.switch(op.OR(t.HLT.HIEle20_Ele12_CaloIdL_TrackIdL_IsoVL_DZ, t.HLT.HIL3DoubleMu0), op.c_float(1.), op.switch(t.HLT.HIL3Mu20, op.c_float(306.913/308.545), op.c_float(264.410/308.545))) ## FIXME these are wrong - you will get the final values from team A else: ## trigger order: dielectron, dimuon or single muon, single electron pd = sample.split("_")[0] if pd == "SingleMuon": trigCut = op.AND(op.NOT(t.HLT.HIEle20_Ele12_CaloIdL_TrackIdL_IsoVL_DZ), op.OR(t.HLT.HIL3DoubleMu0, t.HLT.HIL3Mu20)) elif pd == "HighEGJet": trigCut = op.OR(t.HLT.HIEle20_Ele12_CaloIdL_TrackIdL_IsoVL_DZ, op.AND(op.NOT(op.OR(t.HLT.HIL3DoubleMu0, t.HLT.HIL3Mu20)), t.HLT.HIEle20_WPLoose_Gsf)) noSel = noSel.refine("trig", cut=trigCut, weight=trigWeight) plots = [] def isGoodElectron(el, ptCut=10.): return op.AND( el.pt > ptCut, op.abs(el.eta) < 2.5, el.lostHits == 0, ## do you want this? op.abs(el.sip3d) < 8., op.abs(el.dxy) < .05, op.abs(el.dz ) < .1, el.miniPFRelIso_all < 0.085, el.mvaTTH > 0.125, op.NOT(op.AND(el.jet.isValid, op.OR(el.jet.btagDeepB > .1522, el.jet.btagDeepB <= -999.))) ) def isGoodMuon(mu, ptCut=10.): return op.AND( mu.pt > ptCut, op.abs(mu.eta) < 2.4, mu.mediumPromptId, op.abs(mu.sip3d) < 8., op.abs(mu.dxy) < .05, op.abs(mu.dz ) < .1, mu.miniPFRelIso_all < 0.325, mu.mvaTTH > 0.55, op.NOT(op.AND(mu.jet.isValid, op.OR(mu.jet.btagDeepB > .1522, mu.jet.btagDeepB <= -999.))) ) goodLeptons = { "el" : op.select(t.Electron, partial(isGoodElectron, ptCut=15.)), "mu" : op.select(t.Muon, partial(isGoodMuon, ptCut=15.)) } plots += [ Plot.make1D("trig_nLeptons15", op.rng_len(goodLeptons["el"])+op.rng_len(goodLeptons["mu"]), noSel, EqB(15, 0., 15.)), Plot.make1D("trig_nEl15", op.rng_len(goodLeptons["el"]), noSel, EqB(15, 0., 15.)), Plot.make1D("trig_nMu15", op.rng_len(goodLeptons["mu"]), noSel, EqB(15, 0., 15.)) ] from bamboo.scalefactors import get_scalefactor sf_loose = { "mu": get_scalefactor("lepton", "Muon_RecoToLoose", sfLib=scalefactors_lepMVA, paramDefs=binningVariables_nano_noScaleSyst, systName="muLoose"), "el": get_scalefactor("lepton", "Electron_RecoToLoose", sfLib=scalefactors_lepMVA, paramDefs=binningVariables_nano_noScaleSyst, systName="elLoose") } sf_tight = { "mu": get_scalefactor("lepton", "Muon_LooseToTight", sfLib=scalefactors_lepMVA, paramDefs=binningVariables_nano_noScaleSyst, systName="muTight"), "el": get_scalefactor("lepton", "Electron_LooseToTight", sfLib=scalefactors_lepMVA, paramDefs=binningVariables_nano_noScaleSyst, systName="elTight") } nGoodLeptons = op.rng_len(goodLeptons["el"])+op.rng_len(goodLeptons["mu"]) hasTwoGoodLeptons = noSel.refine("has2Lep", cut=(nGoodLeptons > 1)) # avoid overlap with 1l jets = op.sort(op.select(t.Jet, lambda j : op.AND( j.pt > 25., op.abs(j.eta) < 2.4, j.jetId & 0x2, op.AND( op.NOT(op.rng_any(goodLeptons["el"], lambda l : op.deltaR(l.p4, j.p4) < 0.4)), op.NOT(op.rng_any(goodLeptons["mu"], lambda l : op.deltaR(l.p4, j.p4) < 0.4))) )), lambda j : -j.pt) ## WP: see https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation94X loosebjets = op.select(jets, lambda j : j.btagDeepB > 0.1522) mediumbjets = op.select(jets, lambda j : j.btagDeepB > 0.4941) for fl1,fl2 in product(*repeat(goodLeptons.keys(), 2)): dilepSel = lambda l1,l2 : op.AND( l1.charge != l2.charge, (l1.p4+l2.p4).M() > 12. ) if fl1 == fl2: lGood = op.sort(goodLeptons[fl1], lambda l : -l.pt) dilep = op.combine(lGood, N=2, pred=dilepSel) else: l1Good = op.sort(goodLeptons[fl1], lambda l : -l.pt) l2Good = op.sort(goodLeptons[fl2], lambda l : -l.pt) dilep = op.combine((l1Good, l2Good), pred=dilepSel) ll = dilep[0] hasDilep = hasTwoGoodLeptons.refine(f"hasDilep{fl1}{fl2}", cut=(op.rng_len(dilep) > 0, ll[0].pt > 25.), weight=([ sf_loose[fl1](ll[0]), sf_loose[fl2](ll[1]), sf_tight[fl1](ll[0]), sf_tight[fl2](ll[1]) ] if isMC else None)) plots += [ Plot.make1D(f"dilepton_{fl1}{fl2}_Mll", (ll[0].p4+ll[1].p4).M(), hasDilep, EqB(50, 70, 120.), title="Dilepton mass"), ] # for il,ifl in enumerate((fl1, fl2)): ## plots += [ # Plot.make1D(f"dilepton_{fl1}{fl2}_L{il:d}PT", ll[il].pt, hasDilep, EqB(50, 0., 100.), title=f"Lepton {il:d} PT"), # Plot.make1D(f"dilepton_{fl1}{fl2}_L{il:d}ETA", ll[il].eta, hasDilep, EqB(50, -2.5, 2.5), title=f"Lepton {il:d} ETA"), # ] # plots += [ # Plot.make1D(f"dilepton_{fl1}{fl2}_nJets", op.rng_len(jets), hasDilep, EqB(15, 0, 15.), title="Jet multiplicity"), # Plot.make1D(f"dilepton_{fl1}{fl2}_nLooseBJets", op.rng_len(loosebjets), hasDilep, EqB(15, 0, 15.), title="Loose b-jet multiplicity"), # Plot.make1D(f"dilepton_{fl1}{fl2}_nMediumBJets", op.rng_len(mediumbjets), hasDilep, EqB(15, 0, 15.), title="Medium b-jet multiplicity") # ] return plots
def definePlots(self, tree, noSel, sample=None, sampleCfg=None): plots = [] muons = op.sort(op.select(tree.Muon, lambda mu : op.AND( mu.pt > 5, op.abs(mu.eta) < 2.4, op.abs(mu.pfRelIso04_all) < 0.40, op.abs(mu.dxy) < 0.5, op.abs(mu.dz ) < 1., op.sqrt(mu.dxy**2 + mu.dz**2)/op.sqrt(mu.dxyErr**2+mu.dzErr**2) < 4, ## SIP3D )), lambda mu : -mu.pt) electrons = op.sort(op.select(tree.Electron, lambda el : op.AND( el.pt > 7., op.abs(el.eta) < 2.5, op.abs(el.pfRelIso03_all) < 0.40, op.abs(el.dxy) < 0.5, op.abs(el.dz ) < 1., op.sqrt(el.dxy**2 + el.dz**2)/op.sqrt(el.dxyErr**2+el.dzErr**2) < 4, ## SIP3D )), lambda el : -el.pt) plots += self.controlPlots_2l(noSel, muons, electrons) mZ = 91.1876 def reco_4l(leptons, lName, baseSel): ## select events with four leptons, and find the best Z candidate ## shared between 4el and 4mu has4l = baseSel.refine(f"has4{lName}", cut=[ op.rng_len(leptons) == 4, op.rng_sum(leptons, lambda l : l.charge) == 0, ]) allZcand = op.combine(leptons, N=2, pred=lambda l1,l2 : l1.charge != l2.charge) bestZ = op.rng_min_element_by(allZcand, lambda ll : op.abs(op.invariant_mass(ll[0].p4, ll[1].p4)-mZ)) otherLeptons = op.select(leptons, partial(lambda l,oz=None : op.AND(l.idx != oz[0].idx, l.idx != oz[1].idx), oz=bestZ)) return has4l, bestZ, otherLeptons ## Mixed category: take leading two for each (as in the other implementations def cuts2lMixed(leptons): return [ op.rng_len(leptons) == 2, leptons[0].charge != leptons[1].charge, leptons[0].pt > 20., leptons[1].pt > 10. ] has4lMixed = noSel.refine(f"has4lMixed", cut=cuts2lMixed(muons)+cuts2lMixed(electrons)) mixed_mElEl = op.invariant_mass(electrons[0].p4, electrons[1].p4) mixed_mMuMu = op.invariant_mass(muons[0].p4, muons[1].p4) ## two categories: elel closest to Z or mumu closest to Z has2El2Mu = has4lMixed.refine(f"has2El2Mu", cut=(op.abs(mixed_mElEl-mZ) < op.abs(mixed_mMuMu-mZ))) has2Mu2El = has4lMixed.refine(f"has2Mu2El", cut=(op.abs(mixed_mElEl-mZ) > op.abs(mixed_mMuMu-mZ))) mH_cats = [] for catNm, (has4l, bestZ, otherZ) in { "4Mu" : reco_4l(muons , "Mu", noSel), "4El" : reco_4l(electrons, "El", noSel), "2El2Mu" : (has2El2Mu, electrons, muons), "2Mu2El" : (has2Mu2El, muons, electrons) }.items(): bestZp4 = bestZ[0].p4 + bestZ[1].p4 otherZp4 = otherZ[0].p4 + otherZ[1].p4 hasZZ = has4l.refine(f"{has4l.name}ZZ", cut=[ op.deltaR(bestZ[0].p4 , bestZ[1].p4 ) > 0.02, op.deltaR(otherZ[0].p4, otherZ[1].p4) > 0.02, op.in_range(40., bestZp4.M(), 120.), op.in_range(12., otherZp4.M(), 120.) ]) plots += self.controlPlots_4l(hasZZ, bestZ, otherZ) m4l = (bestZ[0].p4+bestZ[1].p4+otherZ[0].p4+otherZ[1].p4).M() hasZZ_m4l70 = hasZZ.refine(f"{hasZZ.name}m4l70", cut=(m4l > 70.)) p_mH = Plot.make1D(f"H_mass_{catNm}", m4l, hasZZ_m4l70, EqBin(36, 70., 180.), plotopts={"show-overflow": False, "log-y": False, "y-axis-range": [0., 18.]}) mH_cats.append(p_mH) plots.append(p_mH) plots.append(SummedPlot("H_mass", mH_cats)) return plots
def __init__(self, HHself): # All the attributes of the BaseHH are contained in HHself object # All the lambdas will be saved in the highlevelLambdas object to avoid confusions of all the attributes of HH base object # conept # self.conept = lambda lep: op.switch( op.abs(lep.pdgId) == 11, HHself.electron_conept[lep.idx], HHself. muon_conept[lep.idx]) self.electron_conept = lambda ele: HHself.electron_conept[ele.idx] self.muon_conept = lambda mu: HHself.muon_conept[mu.idx] # 4-Momentum association # self.ll_p4 = lambda l1, l2: l1.p4 + l2.p4 self.lljj_p4 = lambda l1, l2, j1, j2: l1.p4 + l2.p4 + j1.p4 + j2.p4 self.lep1j_p4 = lambda lep, j1: lep.p4 + j1.p4 self.lep2j_p4 = lambda lep, j1, j2: lep.p4 + j1.p4 + j2.p4 self.lep3j_p4 = lambda lep, j1, j2, j3: lep.p4 + j1.p4 + j2.p4 + j3.p4 self.lep4j_p4 = lambda lep, j1, j2, j3, j4: lep.p4 + j1.p4 + j2.p4 + j3.p4 + j4.p4 # bReg corr 4 momenta of ak4-bTagged jet # self.bJetCorrP4 = lambda j: op._to.Construct( "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<float> >", (j.pt * j.bRegCorr, j.eta, j.phi, j.mass * j.bRegCorr)).result # Dilep-Met variables # self.DilepMET_deltaPhi = lambda l1, l2, met: self.ll_p4(l1, l2).Phi( ) - met.phi self.DilepMET_Pt = lambda l1, l2, met: op.sqrt( op.pow(met.pt * op.cos(met.phi) + self.ll_p4(l1, l2).Px(), 2) + op. pow(met.pt * op.sin(met.phi) + self.ll_p4(l1, l2).Py(), 2)) # SingleLep-Met variables #self.SinglepMet_Pt = lambda lep,met : op.sqrt(op.pow(met.pt*op.cos(met.phi)+lep.p4.Px(),2)+op.pow(met.pt*op.sin(met.phi)+lep.p4.Py(),2)) self.SinglepMet_Pt = lambda lep, met: (lep.p4 + met.p4).Pt() #self.SinglepMet_dPhi = lambda lep, met : lep.p4.Phi()-met.phi self.SinglepMet_dPhi = lambda lep, met: op.deltaPhi(lep.p4, met.p4) # Transverse mass # self.MT_ll = lambda l1, l2, met: op.sqrt(2 * self.ll_p4(l1, l2).Pt( ) * met.pt * (1 - op.cos(self.ll_p4(l1, l2).Phi() - met.phi))) self.MT_lljj = lambda l1, l2, j1, j2, met: op.sqrt( 2 * self.lljj_p4(l1, l2, j1, j2).Pt() * met.pt * (1 - op.cos(self.lljj_p4(l1, l2, j1, j2).Phi() - met.phi))) self.MT = lambda lep, met: op.sqrt(2 * lep.p4.Pt() * met.pt * ( 1 - op.cos(lep.p4.Phi() - met.phi))) self.MT_W1W2_ljj = lambda lep, j1, j2, met: op.sqrt( 2 * self.lep2j_p4(lep, j1, j2).Pt() * met.pt * (1 - op.cos(self.lep2j_p4(lep, j1, j2).Phi() - met.phi))) self.MT_W1W2_lj = lambda lep, j1, met: op.sqrt( 2 * self.lep1j_p4(lep, j1).Pt() * met.pt * (1 - op.cos(self.lep1j_p4(lep, j1).Phi() - met.phi))) # TODO : clean different versions (eg MT) # dilep + dijet # self.M_lljj = lambda l1, l2, j1, j2: op.invariant_mass( self.lljj_p4(l1, l2, j1, j2)) self.M_HH = lambda l1, l2, j1, j2, met: op.invariant_mass( l1.p4, l2.p4, j1.p4, j2.p4, met.p4) self.MinDR_lj = lambda l1, l2, j1, j2: op.min( op.min(op.deltaR(l1.p4, j1.p4), op.deltaR(l1.p4, j2.p4)), op.min(op.deltaR(l2.p4, j1.p4), op.deltaR(l2.p4, j2.p4))) self.MinDR_part1_partCont = lambda part1, partCont: op.rng_min( partCont, lambda part2: op.deltaR(part1.p4, part2.p4)) self.MinDEta_part1_partCont = lambda part1, partCont: op.rng_min( partCont, lambda part2: op.abs(part1.eta - part2.eta)) self.MinDPhi_part1_partCont = lambda part1, partCont: op.rng_min( partCont, lambda part2: op.abs(op.deltaPhi(part1.p4, part2.p4))) self.MinDR_part1_dipart = lambda part1, dipart: op.min(*( op.deltaR(part1.p4, dipart[i2].p4) for i2 in range(2))) self.JetsMinDR = lambda l, j1, j2: op.min(op.deltaR(l.p4, j1.p4), op.deltaR(l.p4, j2.p4)) self.LepsMinDR = lambda j, l1, l2: op.min(op.deltaR(j.p4, l1.p4), op.deltaR(j.p4, l2.p4)) self.MinDR_lep3j = lambda lep, j1, j2, j3: op.min( op.min(op.deltaR(lep.p4, j1.p4), op.deltaR(lep.p4, j2.p4)), op.deltaR(lep.p4, j3.p4)) self.MinDR_lj = lambda l1, l2, j1, j2: op.min( op.min(op.deltaR(l1.p4, j1.p4), op.deltaR(l1.p4, j2.p4)), op.min(op.deltaR(l2.p4, j1.p4), op.deltaR(l2.p4, j2.p4))) self.MinDR_lep2j = lambda lep, j1, j2: op.min(op.deltaR(lep.p4, j1.p4), op.deltaR(lep.p4, j2.p4)) self.MinDR_lep3j = lambda lep, j1, j2, j3: op.min( op.min(op.deltaR(lep.p4, j1.p4), op.deltaR(lep.p4, j2.p4)), op.deltaR(lep.p4, j3.p4)) self.MinDR_lep4j = lambda lep, j1, j2, j3, j4: op.min( op.min(op.min(op.deltaR(lep.p4, j1.p4), op.deltaR(lep.p4, j2.p4)), op.deltaR(lep.p4, j3.p4)), op.deltaR(lep.p4, j4.p4)) self.MinDPhi_lep2j = lambda lep, j1, j2: op.min( op.abs(op.deltaPhi(lep.p4, j1.p4)), op.abs(op.deltaPhi(lep.p4, j2.p4))) self.MinDPhi_lep3j = lambda lep, j1, j2, j3: op.min( op.min(op.abs(op.deltaPhi(lep.p4, j1.p4)), op.abs(op.deltaPhi(lep.p4, j2.p4))), op.abs(op.deltaPhi(lep.p4, j3.p4))) self.MinDPhi_lep4j = lambda lep, j1, j2, j3, j4: op.min( op.min( op.min(op.abs(op.deltaPhi(lep.p4, j1.p4)), op.abs(op.deltaPhi(lep.p4, j2.p4))), op.abs(op.deltaPhi(lep.p4, j3.p4))), op.abs(op.deltaPhi(lep.p4, j4.p4))) self.MinDEta_lep2j = lambda lep, j1, j2: op.min( op.abs(lep.eta - j1.eta), op.abs(lep.eta - j2.eta)) self.MinDEta_lep3j = lambda lep, j1, j2, j3: op.min( op.min(op.abs(lep.eta - j1.eta), op.abs(lep.eta - j2.eta)), op.abs(lep.eta - j3.eta)) self.MinDEta_lep4j = lambda lep, j1, j2, j3, j4: op.min( op.min(op.min(op.abs(lep.eta - j1.eta), op.abs(lep.eta - j2.eta)), op.abs(lep.eta - j3.eta)), op.abs(lep.eta - j4.eta)) self.MaxDR_lep2j = lambda lep, j1, j2: op.max(op.deltaR(lep.p4, j1.p4), op.deltaR(lep.p4, j2.p4)) self.MaxDR_lep3j = lambda lep, j1, j2, j3: op.max( op.max(op.deltaR(lep.p4, j1.p4), op.deltaR(lep.p4, j2.p4)), op.deltaR(lep.p4, j3.p4)) self.MaxDR_lep4j = lambda lep, j1, j2, j3, j4: op.max( op.max(op.max(op.deltaR(lep.p4, j1.p4), op.deltaR(lep.p4, j2.p4)), op.deltaR(lep.p4, j3.p4)), op.deltaR(lep.p4, j4.p4)) self.MaxDPhi_lep2j = lambda lep, j1, j2: op.max( op.abs(op.deltaPhi(lep.p4, j1.p4)), op.abs(op.deltaPhi(lep.p4, j2.p4))) self.MaxDPhi_lep3j = lambda lep, j1, j2, j3: op.max( op.max(op.abs(op.deltaPhi(lep.p4, j1.p4)), op.abs(op.deltaPhi(lep.p4, j2.p4))), op.abs(op.deltaPhi(lep.p4, j3.p4))) self.MaxDPhi_lep4j = lambda lep, j1, j2, j3, j4: op.max( op.max( op.max(op.abs(op.deltaPhi(lep.p4, j1.p4)), op.abs(op.deltaPhi(lep.p4, j2.p4))), op.abs(op.deltaPhi(lep.p4, j3.p4))), op.abs(op.deltaPhi(lep.p4, j4.p4))) self.MaxDEta_lep2j = lambda lep, j1, j2: op.max( op.abs(lep.eta - j1.eta), op.abs(lep.eta - j2.eta)) self.MaxDEta_lep3j = lambda lep, j1, j2, j3: op.max( op.max(op.abs(lep.eta - j1.eta), op.abs(lep.eta - j2.eta)), op.abs(lep.eta - j3.eta)) self.MaxDEta_lep4j = lambda lep, j1, j2, j3, j4: op.max( op.max(op.max(op.abs(lep.eta - j1.eta), op.abs(lep.eta - j2.eta)), op.abs(lep.eta - j3.eta)), op.abs(lep.eta - j4.eta)) # Higgs related variables # #self.HT2 = lambda l1,l2,j1,j2,met : op.sqrt(op.pow(met.pt*op.cos(met.phi)+l1.p4.Px()+l2.p4.Px(),2)+op.pow(met.pt*op.sin(met.phi)+l1.p4.Py()+l2.p4.Py(),2)) + op.abs((j1.p4+j2.p4).Pt()) #self.HT2R = lambda l1,l2,j1,j2,met : self.HT2(met,l1,l2,j1,j2)/(met.pt+l1.p4.Pt()+l2.p4.Pt()+j1.p4.Pt()+j2.p4.Pt()) #self.HT2_l1jmet = lambda l,j1,met : op.sqrt(op.pow(met.pt*op.cos(met.phi)+l.p4.Px(),2)+op.pow(met.pt*op.sin(met.phi)+l.p4.Py(),2)) + op.abs(j1.p4.Pt()) #self.HT2R_l1jmet = lambda l,j1,met : self.HT2_l1jmet(l,j1,met)/(met.pt+l.p4.Pt()+j1.p4.Pt()) #self.HT2_l2jmet = lambda l,j1,j2,met : op.sqrt(op.pow(met.pt*op.cos(met.phi)+l.p4.Px(),2)+op.pow(met.pt*op.sin(met.phi)+l.p4.Py(),2)) + op.abs((j1.p4+j2.p4).Pt()) #self.HT2R_l2jmet = lambda l,j1,j2,met : self.HT2_l2jmet(l,j1,j2,met)/(met.pt+l.p4.Pt()+j1.p4.Pt()+j2.p4.Pt()) #self.HT2_l3jmet = lambda l,j1,j2,j3,met : op.sqrt(op.pow(met.pt*op.cos(met.phi)+l.p4.Px(),2)+op.pow(met.pt*op.sin(met.phi)+l.p4.Py(),2)) + op.abs((j1.p4+j2.p4+j3.p4).Pt()) self.HT_SL = lambda jets: op.rng_sum(jets, lambda j: j.pt) # 0b self.HT2_0b = lambda l, met: op.abs((met.p4 + l.p4).Pt()) self.HT2R_0b = lambda l, met: self.HT2_0b(l, met) / (met.pt + l.pt) # 1b0Wj self.HT2_1b0Wj = lambda l, j1, met: op.abs( (met.p4 + l.p4).Pt()) + j1.pt self.HT2R_1b0Wj = lambda l, j1, met: self.HT2_1b0Wj(l, j1, met) / ( met.pt + l.pt + j1.pt) # 1b1Wj self.HT2_1b1Wj = lambda l, j1, j3, met: op.abs( (met.p4 + l.p4 + j3.p4).Pt()) + j1.pt self.HT2R_1b1Wj = lambda l, j1, j3, met: self.HT2_1b1Wj( l, j1, j3, met) / (met.pt + l.pt + j1.pt + j3.pt) #2b0Wj self.HT2_2b0Wj = lambda l, j1, j2, met: op.abs( (met.p4 + l.p4).Pt()) + op.abs((j1.p4 + j2.p4).Pt()) self.HT2R_2b0Wj = lambda l, j1, j2, met: self.HT2_2b0Wj( l, j1, j2, met) / (met.pt + l.pt + j1.pt + j2.pt) # 1b2Wj self.HT2_1b2Wj = lambda l, j1, j3, j4, met: op.abs( (met.p4 + l.p4 + j3.p4 + j4.p4).Pt()) + j1.pt self.HT2R_1b2Wj = lambda l, j1, j3, j4, met: self.HT2_1b2Wj( l, j1, j3, j4, met) / (met.pt + l.pt + j1.pt + j3.pt + j4.pt) # 2b1Wj self.HT2_2b1Wj = lambda l, j1, j2, j3, met: op.abs( (met.p4 + l.p4 + j3.p4).Pt()) + op.abs((j1.p4 + j2.p4).Pt()) self.HT2R_2b1Wj = lambda l, j1, j2, j3, met: self.HT2_2b1Wj( l, j1, j2, j3, met) / (met.pt + l.pt + j1.pt + j2.pt + j3.pt) #self.HT2_l4jmet = lambda l,j1,j2,j3,j4,met : op.sqrt(op.pow(met.pt*op.cos(met.phi)+l.p4.Px(),2)+op.pow(met.pt*op.sin(met.phi)+l.p4.Py(),2)) + op.abs((j1.p4+j2.p4+j3.p4+j4.p4).Pt()) # 2b2Wj self.HT2_2b2Wj = lambda l, j1, j2, j3, j4, met: op.abs( (met.p4 + l.p4 + j3.p4 + j4.p4).Pt()) + op.abs( (j1.p4 + j2.p4).Pt()) self.HT2R_2b2Wj = lambda l, j1, j2, j3, j4, met: self.HT2_2b2Wj( l, j1, j2, j3, j4, met) / (met.pt + l.pt + j1.pt + j2.pt + j3.pt + j4.pt) #min j1j2DR self.MinDiJetDRLoose = lambda j1, j2, j3: op.min( op.min(op.deltaR(j1.p4, j2.p4), op.deltaR(j2.p4, j3.p4)), op.deltaR(j1.p4, j3.p4)) self.MinDiJetDRTight = lambda j1, j2, j3, j4: op.min( op.min( op.min(self.MinDiJetDRLoose(j1, j2, j3), op.deltaR( j1.p4, j4.p4)), op.deltaR(j2.p4, j4.p4)), op.deltaR(j3.p4, j4.p4)) self.MinDiJetDEtaLoose = lambda j1, j2, j3: op.min( op.min(op.abs(j1.eta - j2.eta), op.abs(j2.eta - j3.eta)), op.abs(j1.eta - j3.eta)) self.MinDiJetDEtaTight = lambda j1, j2, j3, j4: op.min( op.min( op.min(self.MinDiJetDEtaLoose(j1, j2, j3), op.abs(j1.eta - j4.eta)), op.abs(j2.eta - j4.eta)), op.abs(j3.eta - j4.eta)) self.MinDiJetDPhiLoose = lambda j1, j2, j3: op.min( op.min(op.abs(op.deltaPhi(j1.p4, j2.p4)), op.abs(op.deltaPhi(j2.p4, j3.p4))), op.abs(op.deltaPhi(j1.p4, j3.p4))) self.MinDiJetDPhiTight = lambda j1, j2, j3, j4: op.min( op.min( op.min(self.MinDiJetDPhiLoose(j1, j2, j3), op.abs(op.deltaPhi(j1.p4, j4.p4))), op.abs(op.deltaPhi(j2.p4, j4.p4))), op.abs(op.deltaPhi(j3.p4, j4.p4))) self.MaxDiJetDRLoose = lambda j1, j2, j3: op.max( op.max(op.deltaR(j1.p4, j2.p4), op.deltaR(j2.p4, j3.p4)), op.deltaR(j1.p4, j3.p4)) self.MaxDiJetDRTight = lambda j1, j2, j3, j4: op.max( op.max( op.max(self.MaxDiJetDRLoose(j1, j2, j3), op.deltaR( j1.p4, j4.p4)), op.deltaR(j2.p4, j4.p4)), op.deltaR(j3.p4, j4.p4)) self.MaxDiJetDEtaLoose = lambda j1, j2, j3: op.max( op.max(op.abs(j1.eta - j2.eta), op.abs(j2.eta - j3.eta)), op.abs(j1.eta - j3.eta)) self.MaxDiJetDEtaTight = lambda j1, j2, j3, j4: op.max( op.max( op.max(self.MaxDiJetDEtaLoose(j1, j2, j3), op.abs(j1.eta - j4.eta)), op.abs(j2.eta - j4.eta)), op.abs(j3.eta - j4.eta)) self.MaxDiJetDPhiLoose = lambda j1, j2, j3: op.max( op.max(op.abs(op.deltaPhi(j1.p4, j2.p4)), op.abs(op.deltaPhi(j2.p4, j3.p4))), op.abs(op.deltaPhi(j1.p4, j3.p4))) self.MaxDiJetDPhiTight = lambda j1, j2, j3, j4: op.max( op.max( op.max(self.MaxDiJetDPhiLoose(j1, j2, j3), op.abs(op.deltaPhi(j1.p4, j4.p4))), op.abs(op.deltaPhi(j2.p4, j4.p4))), op.abs(op.deltaPhi(j3.p4, j4.p4))) # ------------------------------------ lambdas for BDT variables ------------------------------------ # # min jet-lep DR self.mindr_lep1_jet = lambda lep, jets: op.deltaR( lep.p4, op.sort(jets, lambda j: op.deltaR(lep.p4, j.p4))[0].p4) # HT self.HTfull = lambda fleps, j1p4, j2p4, j3p4, j4p4: j1p4.Pt( ) + j2p4.Pt() + j3p4.Pt() + j4p4.Pt() + op.rng_sum( fleps, lambda l: l.p4.Pt()) self.HTmiss = lambda fleps, j1p4, j2p4, j3p4: j1p4.Pt() + j2p4.Pt( ) + j3p4.Pt() + op.rng_sum(fleps, lambda l: l.p4.Pt()) # mT2 ET = lambda lepp4: op.sqrt( op.pow(lepp4.M(), 2) + op.pow(lepp4.Pt(), 2)) self.mT2 = lambda jetp4, lepp4, metp4: ( op.pow(jetp4.M(), 2) + op.pow(lepp4.M(), 2) + op.pow(metp4.M(), 2) + 2 * (ET(lepp4) * ET(jetp4) - (lepp4.Px() * jetp4.Px() + lepp4.Py() * jetp4.Py())) + 2 * (ET(lepp4) * ET(metp4) - (lepp4.Px() * metp4.Px() + lepp4.Py() * metp4.Py())) + 2 * (ET(jetp4) * ET(metp4) - (jetp4.Px() * metp4.Px() + jetp4.Py() * metp4.Py()))) # pZ component of met # https://github.com/HEP-KBFI/hh-bbww/blob/f4ab60f81a920268a3f2187b97a58ec449b26883/src/comp_metP4_B2G_18_008.cc # some necessary constants (visP4 = lepP4 + Wjj_simple) # - - - - - used to compute neuP4 - - - - - # ax = lambda visP4, met: 125.18 * 125.18 - op.pow(visP4.M( ), 2) + 2. * visP4.Px() * met.p4.Px() + 2. * visP4.Py() * met.p4.Py() A = lambda visP4: 4.0 * op.pow(visP4.E(), 2) - op.pow(visP4.Pz(), 2) B = lambda visP4, met: -4.0 * ax(visP4, met) * visP4.Pz() C = lambda visP4, met: 4.0 * op.pow(visP4.E(), 2) * (op.pow( met.p4.Px(), 2) + op.pow(met.p4.Py(), 2)) - op.pow( ax(visP4, met), 2) D = lambda visP4, met: (op.pow(B(visP4, met), 2) - 4.0 * A(visP4) * C( visP4, met)) pos = lambda visP4, met: (-B(visP4, met) + op.sqrt(D(visP4, met))) / ( 2. * A(visP4)) neg = lambda visP4, met: (-B(visP4, met) - op.sqrt(D(visP4, met))) / ( 2. * A(visP4)) neuPz = lambda visP4, met: (op.switch( D(visP4, met) < 0., -B(visP4, met) / (2 * A(visP4)), op.switch( op.abs(pos(visP4, met)) < op.abs(neg(visP4, met)), pos(visP4, met), neg(visP4, met)))) # - - - - - - - - - - - - - - - - - - - - - # self.neuP4 = lambda visP4, met: op._to.Construct( "ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<float> >", (met.p4.Px(), met.p4.Py(), neuPz(visP4, met), op.sqrt( op.pow(met.p4.Px(), 2) + op.pow(met.p4.Py(), 2) + op.pow( neuPz(visP4, met), 2)))).result # P4 of W1 (l,neu) self.Wlep_simple = lambda wj1P4, wj2P4, lepP4, met: lepP4 + self.neuP4( wj1P4 + wj2P4 + lepP4, met) # P4 of W2 (j,j) self.Wjj_simple = lambda j1P4, j2P4: j1P4 + j2P4 # DR_HadW_bJet self.dR_HadW_bjet = lambda bP4, j1P4, j2P4: op.deltaR( self.Wjj_simple(j1P4, j2P4), bP4) # P4 of HWW (W1 + W2) self.HWW_simple = lambda wj1P4, wj2P4, lepP4, met: self.Wjj_simple( wj1P4, wj2P4) + self.Wlep_simple(wj1P4, wj2P4, lepP4, met) # dR_HWW self.dR_Hww = lambda j1P4, j2P4, lepP4, met: op.deltaR( self.Wjj_simple(j1P4, j2P4), self.Wlep_simple(j1P4, j2P4, lepP4, met)) self.dEta_Hww = lambda j1P4, j2P4, lepP4, met: op.abs( self.Wjj_simple(j1P4, j2P4).Eta() - self.Wlep_simple( j1P4, j2P4, lepP4, met).Eta()) self.dPhi_Hww = lambda j1P4, j2P4, lepP4, met: op.abs( op.deltaPhi(self.Wjj_simple(j1P4, j2P4), self.Wlep_simple(j1P4, j2P4, lepP4, met))) # P4 of lep + met self.Wlep_met_simple = lambda lepP4, metP4: lepP4 + metP4 # SimpleP4 of HWW (W1 + W2) self.HWW_met_simple = lambda j1P4, j2P4, lepP4, metP4: self.Wjj_simple( j1P4, j2P4) + self.Wlep_met_simple(lepP4, metP4) # Total P4 self.HHP4_simple_met = lambda HbbRegP4, j1P4, j2P4, lepP4, metP4: HbbRegP4 + self.Wjj_simple( j1P4, j2P4) + self.Wlep_met_simple(lepP4, metP4) # CosThetaS calculation #comp_cosThetaS = lambda ob1p4, ob2p4 : op.abs(ob1p4.Boost(-(ob1p4+ob2p4).BoostVector()).CosTheta()) motherPx = lambda ob1p4, ob2p4: (ob1p4.Px() + ob2p4.Px()) motherPy = lambda ob1p4, ob2p4: (ob1p4.Py() + ob2p4.Py()) motherPz = lambda ob1p4, ob2p4: (ob1p4.Pz() + ob2p4.Pz()) motherE = lambda ob1p4, ob2p4: (ob1p4.E() + ob2p4.E()) betaX = lambda ob1p4, ob2p4: motherPx(ob1p4, ob2p4) / motherE( ob1p4, ob2p4) betaY = lambda ob1p4, ob2p4: motherPy(ob1p4, ob2p4) / motherE( ob1p4, ob2p4) betaZ = lambda ob1p4, ob2p4: motherPz(ob1p4, ob2p4) / motherE( ob1p4, ob2p4) beta2 = lambda ob1p4, ob2p4: op.pow(betaX(ob1p4, ob2p4), 2) + op.pow( betaY(ob1p4, ob2p4), 2) + op.pow(betaZ(ob1p4, ob2p4), 2) gamma = lambda ob1p4, ob2p4: 1.0 / op.sqrt(1 - beta2(ob1p4, ob2p4)) betap = lambda ob1p4, ob2p4: betaX(ob1p4, ob2p4) * motherPx( ob1p4, ob2p4) + betaY(ob1p4, ob2p4) * motherPy( ob1p4, ob2p4) + betaZ(ob1p4, ob2p4) * motherPz(ob1p4, ob2p4) gamma2 = lambda ob1p4, ob2p4: op.switch( beta2(ob1p4, ob2p4) > 0, (gamma(ob1p4, ob2p4) - 1) / beta2(ob1p4, ob2p4), op.c_float(0.0)) boostPx = lambda ob1p4, ob2p4: ob1p4.Px() + gamma2( ob1p4, ob2p4) * betap(ob1p4, ob2p4) * betaX(ob1p4, ob2p4) + gamma( ob1p4, ob2p4) * betaX(ob1p4, ob2p4) * ob1p4.E() boostPy = lambda ob1p4, ob2p4: ob1p4.Px() + gamma2( ob1p4, ob2p4) * betap(ob1p4, ob2p4) * betaY(ob1p4, ob2p4) + gamma( ob1p4, ob2p4) * betaY(ob1p4, ob2p4) * ob1p4.E() boostPz = lambda ob1p4, ob2p4: ob1p4.Pz() + gamma2( ob1p4, ob2p4) * betap(ob1p4, ob2p4) * betaZ(ob1p4, ob2p4) + gamma( ob1p4, ob2p4) * betaZ(ob1p4, ob2p4) * ob1p4.E() boostP = lambda ob1p4, ob2p4: op.sqrt( op.pow(boostPx(ob1p4, ob2p4), 2) + op.pow(boostPy(ob1p4, ob2p4), 2) + op.pow(boostPz(ob1p4, ob2p4), 2)) self.comp_cosThetaS = lambda ob1p4, ob2p4: op.abs( boostPz(ob1p4, ob2p4) / boostP(ob1p4, ob2p4)) #BoostP3 = lambda ob1p4,ob2p4 : op._to.Construct("ROOT::Math::TVector<ROOT::Math::PxPyPz3D<float>>",(-motherPx(ob1p4,ob2p4), -motherPy(ob1p4,ob2p4), -motherPz(ob1p4,ob2p4))).result #boost = lambda ob1p4,ob2p4 : op.construct("ROOT::Math::Boost", (-motherPx(ob1p4,ob2p4)/motherE(ob1p4,ob2p4), # -motherPy(ob1p4,ob2p4)/motherE(ob1p4,ob2p4), # -motherPz(ob1p4,ob2p4)/motherE(ob1p4,ob2p4))) #self.comp_cosThetaS = lambda ob1p4,ob2p4 : op.abs(boost(ob1p4,ob2p4)(ob1p4).CosTheta()) #p4_boosted = lambda ob1p4,ob2p4 : op.extMethod("ROOT::Math::Boost{-motherPx(ob1p4,ob2p4)/motherE(ob1p4,ob2p4), -motherPy(ob1p4,ob2p4)/motherE(ob1p4,ob2p4), -motherPz(ob1p4,ob2p4)/motherE(ob1p4,ob2p4)}", returnType=(ob1p4+ob2p4)._typeName)(ob1p4+ob2p4) #self.comp_cosThetaS = lambda ob1p4,ob2p4 : op.deltaR(ob1p4, p4_boosted(ob1p4,ob2p4)) #boost = lambda ob1p4, ob2p4: op.construct("ROOT::Math::Boost", (-betaX(ob1p4, ob2p4), -betaY(ob1p4, ob2p4), -betaZ(ob1p4, ob2p4))) #boostP4 = lambda ob1p4,ob2p4 : boost(ob1p4,ob2p4)(ob1p4) #self.comp_cosThetaS = lambda ob1p4,ob2p4 : op.abs(boostP4(ob1p4,ob2p4).Pz()/op.sqrt(op.pow(boostP4(ob1p4,ob2p4).Px(),2) + op.pow(boostP4(ob1p4,ob2p4).Py(),2) + op.pow(boostP4(ob1p4,ob2p4).Pz(),2))) # MET_LD # Equation 3 (page 33) of AN-2019/111 v13 # Similar to MET, but more robust against pileup jetSumPx = lambda jets: op.rng_sum(jets, lambda j: j.p4.Px()) jetSumPy = lambda jets: op.rng_sum(jets, lambda j: j.p4.Py()) #lepSumPx = lambda leps : op.rng_sum(leps, lambda l : l.p4.Px()) #lepSumPy = lambda leps : op.rng_sum(leps, lambda l : l.p4.Py()) lepSumPx = lambda mus, els: op.rng_sum(mus, lambda l: l.p4.Px( )) + op.rng_sum(els, lambda l: l.p4.Px()) lepSumPy = lambda mus, els: op.rng_sum(mus, lambda l: l.p4.Py( )) + op.rng_sum(els, lambda l: l.p4.Py()) self.MET_LD = lambda met, jets, mus, els: 0.6 * met.pt + 0.4 * op.sqrt( op.pow(jetSumPx(jets) + lepSumPx(mus, els), 2) + op.pow( jetSumPy(jets) + lepSumPy(mus, els), 2)) empty_p4 = op.construct( "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<float> >", ([op.c_float(0.), op.c_float(0.), op.c_float(0.), op.c_float(0.)])) self.MET_LD_DL = lambda met, jets, electrons, muons : 0.6 * met.pt +\ 0.4* (op.rng_sum(jets, (lambda j : j.p4), start=empty_p4) + op.rng_sum(electrons, (lambda e : e.p4), start=empty_p4) + op.rng_sum(muons, (lambda m : m.p4), start=empty_p4)).Pt() # conept self.lambdaConePt = lambda lep: op.switch( op.abs(lep.pdgId) == 13, HHself.muon_conept[lep.idx], HHself. electron_conept[lep.idx]) # angle between 2 planes aDotB = lambda a, b: a.Px() * b.Px() + a.Py() * b.Py() + a.Pz() * b.Pz( ) aMagB = lambda a, b: (op.sqrt( op.pow(a.Px(), 2) + op.pow(a.Py(), 2) + op.pow(a.Pz(), 2))) * ( op.sqrt( op.pow(b.Px(), 2) + op.pow(b.Py(), 2) + op.pow(b.Pz(), 2))) self.angleWWplane = lambda lp4, met, j3p4, j4p4: op.acos( aDotB(j3p4 + j4p4, self.neuP4(j3p4 + j4p4 + lp4, met) + lp4) / aMagB( j3p4 + j4p4, self.neuP4(j3p4 + j4p4 + lp4, met) + lp4)) #self.angleWWplane = lambda lp4, met, j3p4, j4p4 : ((j3p4+j4p4).Vect().Unit()).Angle((self.neuP4(j3p4+j4p4+lp4, met)+lp4).Vect().Unit()) self.angleBetPlanes = lambda j1p4, j2p4, j3p4, j4p4: op.acos( op.c_float( aDotB(j1p4 + j2p4, j3p4 + j4p4) / aMagB( j1p4 + j2p4, j3p4 + j4p4))) self.empty_p4 = op.construct( "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<float> >", ([op.c_float(0.), op.c_float(0.), op.c_float(0.), op.c_float(0.)])) self.MET_LD_DL = lambda met, jets, electrons, muons : 0.6 * met.pt +\ 0.4* (op.rng_sum(jets, (lambda j : j.p4), start=self.empty_p4) + op.rng_sum(electrons, (lambda e : e.p4), start=self.empty_p4) + op.rng_sum(muons, (lambda m : m.p4), start=self.empty_p4)).Pt() self.isBoosted = op.AND( op.rng_len(HHself.ak8BJets) >= 1, op.rng_len(HHself.ak4JetsCleanedFromAk8b) >= 1) #self.isBoosted = op.rng_len(HHself.ak8BJets) >= 1 self.isResolved = op.AND( op.rng_len(HHself.ak4Jets) >= 3, op.rng_len(HHself.ak4BJets) >= 1, op.rng_len(HHself.ak8BJets) == 0) #self.has1Wj = op.rng_len(HHself.probableWJets) == 1 #self.has2Wj = op.rng_len(HHself.wJetsPairs) >= 1 #self.isFullReco = op.AND(op.rng_len(HHself.bJetsByScore) >= 2, op.rng_len(HHself.wJetsPairs) >= 1) #self.isMissReco = op.AND(op.rng_len(HHself.bJetsByScore) >= 2, op.rng_len(HHself.probableWJets) == 1) #self.comp_m_hh_bregcorr = lambda bjets, wjets, lep, met : (op.rng_sum(bjets, (lambda bj : self.bJetCorrP4(bj)), start=empty_p4) + # op.rng_sum(wjets, (lambda wj : self.bJetCorrP4(wj)), start=empty_p4) + # met.p4 + # lep.p4).M() self.comp_m_hh_bregcorr = lambda bjets, wjets, lepconep4, met: ( op.rng_sum(bjets, (lambda bj: self.bJetCorrP4(bj)), start=empty_p4) + op.rng_sum(wjets, (lambda wj: self.bJetCorrP4(wj)), start=empty_p4) + met.p4 + lepconep4).M() #self.comp_pt_hh = lambda bjets, wjets, lep, met : (op.rng_sum(bjets, (lambda bj : bj.p4), start=empty_p4) + # op.rng_sum(wjets, (lambda wj : wj.p4), start=empty_p4) + # met.p4 + # lep.p4).Pt() self.comp_pt_hh = lambda bjets, wjets, lepconep4, met: (op.rng_sum( bjets, (lambda bj: bj.p4), start=empty_p4) + op.rng_sum( wjets, (lambda wj: wj.p4), start=empty_p4) + met.p4 + lepconep4).Pt() #self.comp_dphi_hbb_hww = lambda bjets, wjets, lep, met : op.deltaPhi((op.rng_sum(wjets, (lambda wj : wj.p4), start=empty_p4) + met.p4 + lep.p4), # op.rng_sum(bjets, (lambda bj : bj.p4), start=empty_p4)) #self.comp_dphi_hbb_hwwvis = lambda bjets, wjets, lep : op.deltaPhi((op.rng_sum(wjets, (lambda wj : wj.p4), start=empty_p4) + lep.p4), # op.rng_sum(bjets, (lambda bj : bj.p4), start=empty_p4)) self.comp_dphi_hbb_hww = lambda bjets, wjets, lepconep4, met: op.deltaPhi( (op.rng_sum(wjets, (lambda wj: wj.p4), start=empty_p4) + met.p4 + lepconep4), op.rng_sum(bjets, (lambda bj: bj.p4), start=empty_p4)) self.comp_dphi_hbb_hwwvis = lambda bjets, wjets, lepconep4: op.deltaPhi( (op.rng_sum(wjets, (lambda wj: wj.p4), start=empty_p4) + lepconep4), op.rng_sum(bjets, (lambda bj: bj.p4), start=empty_p4))
def returnHighLevelMVAInputs(self, lep, conep4, bjets, wjets, VBFJetPairs, channel): if channel == 'El': lepconept = self.electron_conept[lep.idx] elif channel == 'Mu': lepconept = self.muon_conept[lep.idx] else: raise RuntimeError('Please mention the correct channel name!') import bamboo.treeoperations as _to def rng_min(rng, fun=(lambda x : x), typeName="float"): return op._to.Reduce.fromRngFun(rng, op.c_float(float("+inf"), typeName), ( lambda fn : ( lambda res, elm : op.extMethod("std::min", returnType="Float_t")(res, fn(elm)) ) )(fun) ) return { #('m_hh_bregcorr', 'm_hh_bregcorr', (50,0,400)) : self.HLL.comp_m_hh_bregcorr(bjets, wjets, lep, self.corrMET), ('m_hh_bregcorr', 'm_hh_bregcorr', (50,0,400)) : self.HLL.comp_m_hh_bregcorr(bjets, wjets, conep4, self.corrMET), #('pt_hh', 'pt_hh', (50,0,400)) : self.HLL.comp_pt_hh(bjets, wjets, lep, self.corrMET), ('pt_hh', 'pt_hh', (50,0,400)) : self.HLL.comp_pt_hh(bjets, wjets, conep4, self.corrMET), ('m_hbb_bregcorr', 'm_hbb_bregcorr', (25,0,200)) : op.multiSwitch((op.rng_len(bjets) == 0, op.c_float(0.)), (op.rng_len(bjets) == 1, self.HLL.getCorrBp4(bjets[0]).M()), op.invariant_mass(self.HLL.getCorrBp4(bjets[0]),self.HLL.getCorrBp4(bjets[1]))), ('pt_hbb', 'pt_hbb', (25,0,200)) : op.multiSwitch((op.rng_len(bjets) == 0, op.c_float(0.)), (op.rng_len(bjets) == 1, bjets[0].pt), (bjets[0].p4 + bjets[1].p4).Pt()), #('m_hww', 'm_hww', (25,0,200)) : op.multiSwitch((op.rng_len(wjets) >= 2, op.invariant_mass(wjets[0].p4 ,wjets[1].p4, self.corrMET.p4, lep.p4)), # (op.rng_len(wjets) == 1, op.invariant_mass(wjets[0].p4 ,self.corrMET.p4, lep.p4)), # op.invariant_mass(self.corrMET.p4, lep.p4)), ('m_hww', 'm_hww', (25,0,200)) : op.multiSwitch((op.rng_len(wjets) >= 2, op.invariant_mass(wjets[0].p4 ,wjets[1].p4, self.corrMET.p4, conep4)), (op.rng_len(wjets) == 1, op.invariant_mass(wjets[0].p4 ,self.corrMET.p4, conep4)), op.invariant_mass(self.corrMET.p4, conep4)), #('pt_hww', 'pt_hww', (25,0,200)) : op.multiSwitch((op.rng_len(wjets) >= 2, (wjets[0].p4 + wjets[1].p4 + self.corrMET.p4 + lep.p4).Pt()), # (op.rng_len(wjets) == 1, (wjets[0].p4 + self.corrMET.p4 + lep.p4).Pt()), # (self.corrMET.p4 + lep.p4).Pt()), ('pt_hww', 'pt_hww', (25,0,200)) : op.multiSwitch((op.rng_len(wjets) >= 2, (wjets[0].p4 + wjets[1].p4 + self.corrMET.p4 + conep4).Pt()), (op.rng_len(wjets) == 1, (wjets[0].p4 + self.corrMET.p4 + conep4).Pt()), (self.corrMET.p4 + conep4).Pt()), ('m_wjj', 'm_wjj', (25,0,200)) : op.multiSwitch((op.rng_len(wjets) >= 2, op.invariant_mass(wjets[0].p4 ,wjets[1].p4)), (op.rng_len(wjets) == 1, wjets[0].mass), op.c_float(0.)), ('pt_wjj', 'pt_wjj', (25,0,200)) : op.multiSwitch((op.rng_len(wjets) >= 2, (wjets[0].p4 + wjets[1].p4).Pt()), (op.rng_len(wjets) == 1, wjets[0].pt), op.c_float(0.)), #('m_wlep', 'm_wlep', (25,0,200)) : op.invariant_mass(self.corrMET.p4, lep.p4), ('m_wlep', 'm_wlep', (25,0,200)) : op.invariant_mass(self.corrMET.p4, conep4), #('pt_wlep', 'pt_wlep', (25,0,200)) : (self.corrMET.p4 + lep.p4).Pt(), ('pt_wlep', 'pt_wlep', (25,0,200)) : (self.corrMET.p4 + conep4).Pt(), ('min_dr_lepbjets', 'min_dr_lepbjets', (25,0,5)) : op.switch(op.rng_len(bjets) > 0, self.HLL.MinDR_part1_partCont(lep, bjets), op.c_float(0.)), #('dphi_hbb_hww', 'dphi_hbb_hww', (22,0,3.2)) : op.abs(self.HLL.comp_dphi_hbb_hww(bjets, wjets, lep, self.corrMET)), ('dphi_hbb_hww', 'dphi_hbb_hww', (22,0,3.2)) : op.abs(self.HLL.comp_dphi_hbb_hww(bjets, wjets, conep4, self.corrMET)), #('dphi_hbb_hwwvis', 'dphi_hbb_hwwvis', (22,0,3.2)) : op.abs(self.HLL.comp_dphi_hbb_hwwvis(bjets, wjets, lep)), ('dphi_hbb_hwwvis', 'dphi_hbb_hwwvis', (22,0,3.2)) : op.abs(self.HLL.comp_dphi_hbb_hwwvis(bjets, wjets, conep4)), #('dphi_met_lep', 'dphi_met_lep', (22,0,3.2)) : op.abs(op.deltaPhi(self.corrMET.p4, lep.p4)), ('dphi_met_lep', 'dphi_met_lep', (22,0,3.2)) : op.abs(op.deltaPhi(self.corrMET.p4, conep4)), ('dphi_met_hbb', 'dphi_met_hbb', (22,0,3.2)) : op.multiSwitch((op.rng_len(bjets) >= 2, op.abs(op.deltaPhi(self.corrMET.p4,(bjets[0].p4 + bjets[1].p4)))), (op.rng_len(bjets) == 1, op.abs(op.deltaPhi(self.corrMET.p4, bjets[0].p4))), op.c_float(0.)), ('dphi_met_wjj', 'dphi_met_wjj', (22,0,3.2)) : op.multiSwitch((op.rng_len(wjets) >= 2, op.abs(op.deltaPhi(self.corrMET.p4,(wjets[0].p4 + wjets[1].p4)))), (op.rng_len(wjets) == 1, op.abs(op.deltaPhi(self.corrMET.p4,wjets[0].p4))), op.c_float(0.)), ('dr_lep_hbb', 'dr_lep_hbb', (25,0,5)) : op.multiSwitch((op.rng_len(bjets) >= 2, op.deltaR(conep4, (bjets[0].p4+bjets[1].p4))), (op.rng_len(bjets) == 1, op.deltaR(conep4, bjets[0].p4)), op.c_float(0.)), ('dr_lep_wjj', 'dr_lep_wjj', (25,0,5)) : op.multiSwitch((op.rng_len(wjets) >= 2, op.deltaR(conep4, (wjets[0].p4+wjets[1].p4))), (op.rng_len(wjets) == 1, op.deltaR(conep4, wjets[0].p4)), op.c_float(0.)), ('min_dr_wjets', 'min_dr_wjets', (25,0,5)) : op.switch(op.rng_len(wjets) >= 2, op.deltaR(wjets[0].p4, wjets[1].p4), op.c_float(0.)), ('min_dhi_wjets', 'min_dphi_wjets', (22,0,3.2)) : op.switch(op.rng_len(wjets) >= 2, op.abs(op.deltaPhi(wjets[0].p4,wjets[1].p4)),op.c_float(0.)), ('min_dr_bjets', 'min_dr_bjets', (25,0,5)) : op.switch(op.rng_len(bjets) >= 2, op.deltaR(bjets[0].p4,bjets[1].p4), op.c_float(0.)), ('min_dphi_bjets', 'min_dphi_bjets', (22,0,3.2)) : op.switch(op.rng_len(bjets) >= 2, op.abs(op.deltaPhi(bjets[0].p4,bjets[1].p4)),op.c_float(0.)), ('ht', 'ht', (50,0,300)) : op.rng_sum(self.ak4Jets, lambda j : j.pt), #('smin', 'smin', (50,0,300)) : self.HLL.comp_smin(lep,self.corrMET,self.ak4Jets,bjets,wjets), ('smin', 'smin', (50,0,300)) : self.HLL.comp_smin(conep4,self.corrMET,self.ak4Jets,bjets,wjets), ('vbf_pair_mass', 'vbf_pair_mass', (50,0,300)) : op.switch(op.rng_len(VBFJetPairs) > 0,op.invariant_mass(VBFJetPairs[0][0].p4, VBFJetPairs[0][1].p4), op.c_float(0.)), ('vbf_pairs_absdeltaeta', 'vbf_pairs_absdeltaeta', (22,0,3.2)) : op.switch(op.rng_len(VBFJetPairs) > 0,op.abs(VBFJetPairs[0][0].eta - VBFJetPairs[0][1].eta), op.c_float(0.)), ('lep_conept', 'lep_conept', (25,0,200)) : lepconept, ('VBF_tag', 'vbf_tag', (2,0,2)) : op.c_int(op.rng_len(VBFJetPairs) > 0), ('boosted_tag', 'boosted_tag', (2,0,2)) : op.c_int(op.rng_len(self.ak8BJets) > 0), ('n_btag', 'n_btag', (5,0,5)) : op.c_float(op.rng_len(self.ak4BJets)), ('sphericity', 'sphericity', (1,0,1)) : op.c_float(0.), # not used ('sphericity_T', 'sphericity_T', (1,0,1)) : op.c_float(0.), # not used ('aplanarity', 'aplanarity', (1,0,1)) : op.c_float(0.), # not used ('eventshape_C', 'eventshape_C', (1,0,1)) : op.c_float(0.), # not used ('eventshape_D', 'eventshape_D', (1,0,1)) : op.c_float(0.), # not used ('eventshape_Y', 'eventshape_Y', (1,0,1)) : op.c_float(0.), # not used ('foxwolfram1', 'foxwolfram1', (1,0,1)) : op.c_float(0.), # not used ('foxwolfram2', 'foxwolfram2', (1,0,1)) : op.c_float(0.), # not used ('foxwolfram3', 'foxwolfram3', (1,0,1)) : op.c_float(0.), # not used ('foxwolfram4', 'foxwolfram4', (1,0,1)) : op.c_float(0.), # not used ('foxwolfram5', 'foxwolfram5', (1,0,1)) : op.c_float(0.), # not used ('centrality', 'centrality', (1,0,1)) : op.c_float(0.), # not used ('centrality_jets', 'centrality_jets', (1,0,1)) : op.c_float(0.), # not used ('eigenvalue1', 'eigenvalue1', (1,0,1)) : op.c_float(0.), # not used ('eigenvalue2', 'eigenvalue2', (1,0,1)) : op.c_float(0.), # not used ('eigenvalue3', 'eigenvalue3', (1,0,1)) : op.c_float(0.), # not used ('sphericity_met', 'sphericity_met', (1,0,1)) : op.c_float(0.), # not used ('sphericity_T_met', 'sphericity_T_met', (1,0,1)) : op.c_float(0.), # not used ('aplanarity_met', 'aplanarity_met', (1,0,1)) : op.c_float(0.), # not used ('eventshape_C_met', 'eventshape_C_met', (1,0,1)) : op.c_float(0.), # not used ('eventshape_D_met', 'eventshape_D_met', (1,0,1)) : op.c_float(0.), # not used ('eventshape_Y_met', 'eventshape_Y_met', (1,0,1)) : op.c_float(0.), # not used ('foxwolfram1_met', 'foxwolfram1_met', (1,0,1)) : op.c_float(0.), # not used ('foxwolfram2_met', 'foxwolfram2_met', (1,0,1)) : op.c_float(0.), # not used ('foxwolfram3_met', 'foxwolfram3_met', (1,0,1)) : op.c_float(0.), # not used ('foxwolfram4_met', 'foxwolfram4_met', (1,0,1)) : op.c_float(0.), # not used ('foxwolfram5_met', 'foxwolfram5_met', (1,0,1)) : op.c_float(0.), # not used ('centrality_met', 'centrality_met', (1,0,1)) : op.c_float(0.), # not used ('centrality_jets_met','centrality_jets_met', (1,0,1)) : op.c_float(0.), # not used ('eigenvalue1_met', 'eigenvalue1_met', (1,0,1)) : op.c_float(0.), # not used ('eigenvalue2_met', 'eigenvalue2_met', (1,0,1)) : op.c_float(0.), # not used ('eigenvalue3_met', 'eigenvalue3_met', (1,0,1)) : op.c_float(0.) # not used }
def definePlots(self, t, noSel, sample=None, sampleCfg=None): from bamboo.plots import Plot, CutFlowReport from bamboo.plots import EquidistantBinning as EqB from bamboo import treefunctions as op plots = [] #definitions electrons = op.select(t.elec, lambda el : op.AND( el.pt > 20., op.abs(el.eta) < 2.5 )) muons = op.select(t.muon, lambda mu : op.AND( mu.pt > 20., op.abs(mu.eta) < 2.5 )) cleanedElectrons = op.select(electrons, lambda el : op.NOT( op.rng_any(muons, lambda mu : op.deltaR(el.p4, mu.p4) < 0.3 ) )) # we are taking the second isopass to be on which is equal to the medium working point isolatedElectrons = op.select(cleanedElectrons, lambda el : el.isopass & (1<<2) ) identifiedElectrons = op.select(isolatedElectrons, lambda el : el.idpass & (1<<2) ) cleanedMuons = op.select(muons, lambda mu : op.NOT( op.rng_any(electrons, lambda el : op.deltaR(mu.p4, el.p4) < 0.3 ) )) isolatedMuons = op.select(cleanedMuons, lambda mu : mu.isopass & (1<<2) ) identifiedMuons = op.select(isolatedMuons, lambda mu : mu.idpass & (1<<2) ) InvMassMuMU = op.invariant_mass(identifiedMuons[0].p4, identifiedMuons[1].p4 ) cleanedJets = op.select(t.jetpuppi, lambda j : op.AND( op.NOT(op.rng_any(identifiedElectrons, lambda el : op.deltaR(el.p4, j.p4) < 0.3) ), op.NOT(op.rng_any(identifiedMuons, lambda mu : op.deltaR(mu.p4, j.p4) < 0.3) ) )) cleanedGoodJets = op.select(cleanedJets, lambda j : op.AND( j.pt > 30, op.abs(j.eta) < 2.5 )) btaggedJets = op.select(cleanedGoodJets, lambda j : j.btag & (1<<2)) met = op.select(t.metpuppi) #selections #selection1 : Oppositely charged MuMu selection sel1 = noSel.refine("nmumu", cut = [op.AND( (op.rng_len(identifiedMuons) > 1), (op.product(identifiedMuons[0].charge, identifiedMuons[1].charge) < 0 ))]) #selection2 : Invariant mass selection sel2 = sel1.refine("InvM", cut = [op.NOT(op.in_range(76, InvMassMuMU, 106))]) #selection3 : two jets selection sel3 = sel2.refine("njet", cut = [op.rng_len(cleanedGoodJets) > 1]) #selection4 : at least 1 among two leading jets is b-tagged sel4 = sel3.refine("btag", cut = [op.OR( cleanedGoodJets[0].btag & (1<<2), cleanedGoodJets[1].btag & (1<<2))]) #selection5 : MET > 40 GeV sel5 = sel4.refine("MET", cut = [met[0].pt > 40]) #plots #noSel plots.append(Plot.make1D("nJetsNoSel", op.rng_len(cleanedGoodJets), noSel, EqB(10, 0., 10.), title="nJets")) plots.append(Plot.make1D("nbtaggedJetsNoSel", op.rng_len(btaggedJets), noSel, EqB(10, 0., 10.), title="nbtaggedJets")) plots.append(Plot.make1D("nMuNoSel", op.rng_len(identifiedMuons), noSel, EqB(15, 0., 15.), title="nMuons")) plots.append(Plot.make1D("METptNoSel", met[0].pt, noSel, EqB(50, 0., 250), title="MET_PT")) #sel1 plots.append(Plot.make1D("nJetsSel1", op.rng_len(cleanedGoodJets), sel1, EqB(10, 0., 10.), title="nJets")) plots.append(Plot.make1D("nbtaggedJetsSel1", op.rng_len(btaggedJets), sel1, EqB(10, 0., 10.), title="nbtaggedJets")) plots.append(Plot.make1D("nMuSel1", op.rng_len(identifiedMuons), sel1, EqB(10, 0., 10.), title="nMuons")) plots.append(Plot.make1D("InvMassTwoMuonsSel1", InvMassMuMU, sel1, EqB(30, 0, 300), title="m(ll)")) plots.append(Plot.make1D("LeadingMuonPTSel1", muons[0].pt, sel1, EqB(30, 0., 250.), title=" Leading Muon PT")) plots.append(Plot.make1D("SubLeadingMuonPTSel1", muons[1].pt, sel1, EqB(30, 0., 250.), title="SubLeading Muon PT")) plots.append(Plot.make1D("LeadingMuonEtaSel1", muons[0].eta, sel1, EqB(30, -3, 3), title=" Leading Muon eta")) plots.append(Plot.make1D("SubLeadingMuonEtaSel1", muons[1].eta, sel1, EqB(30, -3, 3), title="SubLeading Muon eta")) plots.append(Plot.make1D("METptSel1", met[0].pt, sel1, EqB(50, 0., 250), title="MET_PT")) #sel2 plots.append(Plot.make1D("nJetsSel2", op.rng_len(cleanedGoodJets), sel2, EqB(10, 0., 10.), title="nJets")) plots.append(Plot.make1D("nbtaggedJetsSel2", op.rng_len(btaggedJets), sel2, EqB(10, 0., 10.), title="nbtaggedJets")) plots.append(Plot.make1D("nMuSel2", op.rng_len(identifiedMuons), sel2, EqB(10, 0., 10.), title="nMuons")) plots.append(Plot.make1D("InvMassTwoMuonsSel2", InvMassMuMU, sel2, EqB(20, 20., 300.), title="m(ll)")) plots.append(Plot.make1D("LeadingMuonPTSel2", muons[0].pt, sel2, EqB(30, 0., 250.), title=" Leading Muon PT")) plots.append(Plot.make1D("SubLeadingMuonPTSel2", muons[1].pt, sel2, EqB(30, 0., 200.), title=" SubLeading Muon PT")) plots.append(Plot.make1D("LeadingMuonEtaSel2", muons[0].eta, sel2, EqB(30, -3, 3), title=" Leading Muon Eta")) plots.append(Plot.make1D("SubLeadingMuonEtaSel2", muons[1].eta, sel2, EqB(30, -3, 3), title=" SubLeading Muon Eta")) plots.append(Plot.make1D("METptSel2", met[0].pt, sel2, EqB(50, 0., 250), title="MET_PT")) #sel3 plots.append(Plot.make1D("nJetsSel3", op.rng_len(cleanedGoodJets), sel3, EqB(10, 0., 10.), title="nJets")) plots.append(Plot.make1D("nbtaggedJetsSel3", op.rng_len(btaggedJets), sel3, EqB(10, 0., 10.), title="nbtaggedJets")) plots.append(Plot.make1D("LeadingJetPTSel3", cleanedGoodJets[0].pt, sel3, EqB(50, 0., 350.), title="Leading jet PT")) plots.append(Plot.make1D("SubLeadingJetPTSel3", cleanedGoodJets[1].pt, sel3, EqB(50, 0., 350.), title="SubLeading jet PT")) plots.append(Plot.make1D("LeadingJetEtaSel3", cleanedGoodJets[0].eta, sel3, EqB(30, -3, 3), title="Leading jet Eta")) plots.append(Plot.make1D("SubLeadingJetEtaSel3", cleanedGoodJets[1].eta, sel3, EqB(30, -3, 3), title="SubLeading jet Eta")) plots.append(Plot.make1D("nMuSel3", op.rng_len(identifiedMuons), sel3, EqB(10, 0., 10.), title="nMuons")) plots.append(Plot.make1D("LeadingMuonPTSel3", muons[0].pt, sel3, EqB(30, 0., 250.), title=" Leading Muon PT")) plots.append(Plot.make1D("SubLeadingMuonPTSel3", muons[1].pt, sel3, EqB(30, 0., 200.), title=" SubLeading Muon PT")) plots.append(Plot.make1D("LeadingMuonEtaSel3", muons[0].eta, sel3, EqB(30, -3, 3), title=" Leading Muon Eta")) plots.append(Plot.make1D("SubLeadingMuonEtaSel3", muons[1].eta, sel3, EqB(30, -3, 3), title=" SubLeading Muon Eta")) plots.append(Plot.make1D("InvMassTwoMuonsSel3", InvMassMuMU, sel3, EqB(30, 0, 300), title="m(ll)")) plots.append(Plot.make1D("METptSel3", met[0].pt, sel3, EqB(50, 0., 250), title="MET_PT")) #sel4 plots.append(Plot.make1D("nJetsSel4", op.rng_len(cleanedGoodJets), sel4, EqB(10, 0, 10), title="nJets")) plots.append(Plot.make1D("nbtaggedJetsSel4", op.rng_len(btaggedJets), sel4, EqB(10, 0., 10.), title="nbtaggedJets")) plots.append(Plot.make1D("LeadingJetPTSel4", cleanedGoodJets[0].pt, sel4, EqB(50, 0., 250.), title="Leading jet PT")) plots.append(Plot.make1D("SubLeadingJetPTSel4", cleanedGoodJets[1].pt, sel4, EqB(50, 0., 250.), title="SubLeading jet PT")) plots.append(Plot.make1D("LeadingJetEtaSel4", cleanedGoodJets[0].eta, sel4, EqB(30, -3, 3.), title="Leading jet Eta")) plots.append(Plot.make1D("SubLeadingJetEtaSel4", cleanedGoodJets[1].eta, sel4, EqB(30, -3, 3.), title="SubLeading jet Eta")) plots.append(Plot.make1D("nMuSel4", op.rng_len(identifiedMuons), sel4, EqB(10, 0., 10.), title="nMuons")) plots.append(Plot.make1D("LeadingMuonPTSel4", muons[0].pt, sel4, EqB(30, 0., 250.), title=" Leading Muon PT")) plots.append(Plot.make1D("SubLeadingMuonPTSel4", muons[1].pt, sel4, EqB(30, 0., 200.), title=" SubLeading Muon PT")) plots.append(Plot.make1D("LeadingMuonEtaSel4", muons[0].eta, sel4, EqB(30, -3, 3), title=" Leading Muon Eta")) plots.append(Plot.make1D("SubLeadingMuonEtaSel4", muons[1].eta, sel4, EqB(30, -3, 3), title=" SubLeading Muon Eta")) plots.append(Plot.make1D("InvMassTwoMuonsSel4", InvMassMuMU, sel4, EqB(30, 0, 300), title="m(ll)")) plots.append(Plot.make1D("METptSel4", met[0].pt, sel4, EqB(50, 0., 250), title="MET_PT")) #sel5 plots.append(Plot.make1D("nJetsSel5", op.rng_len(cleanedGoodJets), sel5, EqB(10, 0, 10), title="nJets")) plots.append(Plot.make1D("nbtaggedJetsSel5", op.rng_len(btaggedJets), sel5, EqB(10, 0., 10.), title="nbtaggedJets")) plots.append(Plot.make1D("LeadingJetPTSel5", cleanedGoodJets[0].pt, sel5, EqB(50, 0., 250.), title="Leading jet PT")) plots.append(Plot.make1D("SubLeadingJetPTSel5", cleanedGoodJets[1].pt, sel5, EqB(50, 0., 250.), title="SubLeading jet PT")) plots.append(Plot.make1D("LeadingJetEtaSel5", cleanedGoodJets[0].eta, sel5, EqB(30, -3, 3.), title="Leading jet Eta")) plots.append(Plot.make1D("SubLeadingJetEtaSel5", cleanedGoodJets[1].eta, sel5, EqB(30, -3, 3.), title="SubLeading jet Eta")) plots.append(Plot.make1D("nMuSel5", op.rng_len(identifiedMuons), sel5, EqB(10, 0., 10.), title="nMuons")) plots.append(Plot.make1D("LeadingMuonPTSel5", muons[0].pt, sel5, EqB(30, 0., 250.), title=" Leading Muon PT")) plots.append(Plot.make1D("SubLeadingMuonPTSel5", muons[1].pt, sel5, EqB(30, 0., 200.), title=" SubLeading Muon PT")) plots.append(Plot.make1D("LeadingMuonEtaSel5", muons[0].eta, sel5, EqB(30, -3, 3), title=" Leading Muon Eta")) plots.append(Plot.make1D("SubLeadingMuonEtaSel5", muons[1].eta, sel5, EqB(30, -3, 3), title=" SubLeading Muon Eta")) plots.append(Plot.make1D("InvMassTwoMuonsSel5", InvMassMuMU, sel5, EqB(30, 0, 300), title="m(ll)")) plots.append(Plot.make1D("METptSel5", met[0].pt, sel5, EqB(50, 0., 250), title="MET_PT > 40")) # Efficiency Report on terminal and the .tex output cfr = CutFlowReport("yields") cfr.add(noSel, "Sel0: No selection") cfr.add(sel1, "Sel1: nMuMu >= 2") cfr.add(sel2, "Sel2: InvM") cfr.add(sel3, "Sel3: nJet >= 2") cfr.add(sel4, "Sel4: btag") cfr.add(sel5, "Sel5: MET") plots.append(cfr) return plots
def __init__(self, HHself): # All the attributes of the BaseHH are contained in HHself object # All the lambdas will be saved in the highlevelLambdas object to avoid confusions of all the attributes of HH base object # 4-Momentum association # self.ll_p4 = lambda l1, l2: l1.p4 + l2.p4 self.lljj_p4 = lambda l1, l2, j1, j2: l1.p4 + l2.p4 + j1.p4 + j2.p4 self.lep1j_p4 = lambda lep, j1: lep.p4 + j1.p4 self.lep2j_p4 = lambda lep, j1, j2: lep.p4 + j1.p4 + j2.p4 self.lep3j_p4 = lambda lep, j1, j2, j3: lep.p4 + j1.p4 + j2.p4 + j3.p4 self.lep4j_p4 = lambda lep, j1, j2, j3, j4: lep.p4 + j1.p4 + j2.p4 + j3.p4 + j4.p4 # bReg corr 4 momenta of ak4-bTagged jet # self.bJetCorrP4 = lambda j: op._to.Construct( "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<float> >", (j.pt * j.bRegCorr, j.eta, j.phi, j.mass)).result # Dilep-Met variables # self.DilepMET_deltaPhi = lambda l1, l2, met: self.ll_p4(l1, l2).Phi( ) - met.phi self.DilepMET_Pt = lambda l1, l2, met: op.sqrt( op.pow(met.pt * op.cos(met.phi) + self.ll_p4(l1, l2).Px(), 2) + op. pow(met.pt * op.sin(met.phi) + self.ll_p4(l1, l2).Py(), 2)) # SingleLep-Met variables self.SinglepMet_Pt = lambda lep, met: op.sqrt( op.pow(met.pt * op.cos(met.phi) + lep.p4.Px(), 2) + op.pow( met.pt * op.sin(met.phi) + lep.p4.Py(), 2)) self.SinglepMet_dPhi = lambda lep, met: lep.p4.Phi() - met.phi # Transverse mass # self.MT_ll = lambda l1, l2, met: op.sqrt(2 * self.ll_p4(l1, l2).Pt( ) * met.pt * (1 - op.cos(self.ll_p4(l1, l2).Phi() - met.phi))) self.MT_lljj = lambda l1, l2, j1, j2, met: op.sqrt( 2 * self.lljj_p4(l1, l2, j1, j2).Pt() * met.pt * (1 - op.cos(self.lljj_p4(l1, l2, j1, j2).Phi() - met.phi))) self.MT = lambda lep, met: op.sqrt(2 * lep.p4.Pt() * met.pt * ( 1 - op.cos(lep.p4.Phi() - met.phi))) self.MT_W1W2_ljj = lambda lep, j1, j2, met: op.sqrt( 2 * self.lep2j_p4(lep, j1, j2).Pt() * met.pt * (1 - op.cos(self.lep2j_p4(lep, j1, j2).Phi() - met.phi))) self.MT_W1W2_lj = lambda lep, j1, met: op.sqrt( 2 * self.lep1j_p4(lep, j1).Pt() * met.pt * (1 - op.cos(self.lep1j_p4(lep, j1).Phi() - met.phi))) # TODO : clean different versions (eg MT) # dilep + dijet # self.M_lljj = lambda l1, l2, j1, j2: op.invariant_mass( self.lljj_p4(l1, l2, j1, j2)) self.MinDR_lj = lambda l1, l2, j1, j2: op.min( op.min(op.deltaR(l1.p4, j1.p4), op.deltaR(l1.p4, j2.p4)), op.min(op.deltaR(l2.p4, j1.p4), op.deltaR(l2.p4, j2.p4))) self.MinDR_lep3j = lambda lep, j1, j2, j3: op.min( op.min(op.deltaR(lep.p4, j1.p4), op.deltaR(lep.p4, j2.p4)), op.deltaR(lep.p4, j3.p4)) # Higgs related variables # self.HT2 = lambda l1, l2, j1, j2, met: op.sqrt( op.pow(met.pt * op.cos(met.phi) + l1.p4.Px() + l2.p4.Px(), 2) + op. pow(met.pt * op.sin(met.phi) + l1.p4.Py() + l2.p4.Py(), 2 )) + op.abs((j1.p4 + j2.p4).Pt()) self.HT2R = lambda l1, l2, j1, j2, met: self.HT2( met, l1, l2, j1, j2) / (met.pt + l1.p4.Pt() + l2.p4.Pt() + j1.p4. Pt() + j2.p4.Pt()) self.HT2_l3jmet = lambda l, j1, j2, j3, met: op.sqrt( op.pow(met.pt * op.cos(met.phi) + l.p4.Px(), 2) + op.pow( met.pt * op.sin(met.phi) + l.p4.Py(), 2)) + op.abs( (j1.p4 + j2.p4 + j3.p4).Pt()) self.HT2R_l3jmet = lambda l, j1, j2, j3, met: self.HT2_l3jmet( met, l, j1, j2, j3) / (met.pt + l.p4.Pt() + j1.p4.Pt() + j2.p4.Pt( ) + j3.p4.Pt()) self.HT2_l4jmet = lambda l, j1, j2, j3, j4, met: op.sqrt( op.pow(met.pt * op.cos(met.phi) + l.p4.Px(), 2) + op.pow( met.pt * op.sin(met.phi) + l.p4.Py(), 2)) + op.abs( (j1.p4 + j2.p4 + j3.p4 + j4.p4).Pt()) self.HT2R_l4jmet = lambda l, j1, j2, j3, j4, met: self.HT2_l4jmet( met, l, j1, j2, j3, j4) / (met.pt + l.p4.Pt() + j1.p4.Pt() + j2.p4. Pt() + j3.p4.Pt() + j4.p4.Pt()) #min j1j2DR self.MinDiJetDRLoose = lambda j1, j2, j3: op.min( op.min(op.deltaR(j1.p4, j2.p4), op.deltaR(j2.p4, j3.p4)), op.deltaR(j1.p4, j3.p4)) # ------------------------------------ lambdas for BDT variables ------------------------------------ # self.mindr_lep1_jet = lambda lep, jets: op.deltaR( lep.p4, op.sort(jets, lambda j: op.deltaR(lep.p4, j.p4))[0].p4) self.HT = lambda jets: op.rng_sum(jets, lambda j: j.p4.Pt()) # mT2 self.ET = lambda lep: op.sqrt( op.pow(lep.p4.M(), 2) + op.pow(lep.p4.Pt(), 2)) self.mT2 = lambda jet, lep, met: ( op.pow(jet.p4.M(), 2) + op.pow(lep.p4.M(), 2) + op.pow( met.p4.M(), 2) + 2 * (ET(lep) * ET(jet) - (lep.p4.Px() * jet.p4.Px() + lep.p4.Py() * jet.p4.Py())) + 2 * (ET(lep) * ET(met) - (lep.p4.Px() * met.p4.Px() + lep.p4.Py() * met.p4.Py())) + 2 * (ET(jet) * ET(met) - (jet.p4.Px() * met.p4.Px() + jet.p4.Py() * met.p4.Py()))) # pZ component of met # https://github.com/HEP-KBFI/hh-bbww/blob/f4ab60f81a920268a3f2187b97a58ec449b26883/src/comp_metP4_B2G_18_008.cc # some necessary constants (visP4 = lepP4 + Wjj_simple) # - - - - - used to compute neuP4 - - - - - # _a = lambda visP4, met, mH: (op.pow(mH, 2) - op.pow(visP4.M( ), 2) + 2. * visP4.Px() * met.p4.Px() + 2. * visP4.Py() * met.p4.Py()) _A = lambda visP4: 4.0 * op.pow(visP4.E(), 2) - op.pow(visP4.Pz(), 2) _B = lambda visP4, met, mH: -4.0 * _a(visP4, met, mH) * visP4.Pz() _C = lambda visP4, met, mH: 4.0 * op.pow(visP4.E(), 2) * (op.pow( met.p4.Px(), 2) + op.pow(met.p4.Py(), 2)) - op.pow( _a(visP4, met, mH), 2) _D = lambda visP4, met, mH: (op.pow(_B(visP4, met, mH), 2) - 4.0 * _A( visP4) * _C(visP4, met, mH)) _pos = lambda visP4, met, mH: (-_B(visP4, met, mH) + op.sqrt( _D(visP4, met, mH))) / (2. * _A(visP4)) _neg = lambda visP4, met, mH: (-_B(visP4, met, mH) - op.sqrt( _D(visP4, met, mH))) / (2. * _A(visP4)) neuPz = lambda visP4, met, mH: (op.switch( _D(visP4, met, mH) < 0., -_B(visP4, met, mH) / (2. * _A(visP4)), op.switch( op.abs(_pos(visP4, met, mH)) < op.abs(_neg(visP4, met, mH)), _pos(visP4, met, mH), _neg(visP4, met, mH)))) # - - - - - - - - - - - - - - - - - - - - - # neuP4 = lambda visP4, met, mH: op._to.Construct( "ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<float> >", (met.p4.Px(), met.p4.Py(), neuPz(visP4, met, mH), op.sqrt( op.pow(met.p4.Px(), 2) + op.pow(met.p4.Py(), 2) + op.pow( neuPz(visP4, met, mH), 2)))).result # P4 of W1 (l,neu) self.Wlep_simple = lambda j1P4, j2P4, lepP4, met, mH: lepP4 + neuP4( j1P4 + j2P4 + lepP4, met, mH) # P4 of W2 (j,j) self.Wjj_simple = lambda j1P4, j2P4: j1P4 + j2P4 # P4 of HWW (W1 + W2) self.HWW_simple = lambda j1P4, j2P4, lepP4, met, mH: Wjj_simple( j1P4, j2P4) + Wlep_simple(lepP4, neuP4(j1P4 + j2P4 + lepP4, met, mH )) # dR_HWW self.dR_Hww = lambda j1P4, j2P4, lepP4, met, mH: op.deltaR( Wjj_simple(j1P4, j2P4), Wlep_simple(j1P4, j2P4, lepP4, met, mH)) # P4 of lep + met self.Wlep_met_simple = lambda lepP4, metP4: lepP4 + metP4 # SimpleP4 of HWW (W1 + W2) self.HWW_met_simple = lambda j1P4, j2P4, lepP4, metP4: Wjj_simple( j1P4, j2P4) + Wlep_met_simple(lepP4, metP4) # Total P4 self.HHP4_simple_met = lambda HbbRegP4, j1P4, j2P4, lepP4, metP4: HbbRegP4 + Wjj_simple( j1P4, j2P4) + Wlep_met_simple(lepP4, metP4) # CosThetaS calculation #comp_cosThetaS = lambda ob1p4, ob2p4 : op.abs(ob1p4.Boost(-(ob1p4+ob2p4).BoostVector()).CosTheta()) motherPx = lambda ob1p4, ob2p4: (ob1p4.Px() + ob2p4.Px()) motherPy = lambda ob1p4, ob2p4: (ob1p4.Py() + ob2p4.Py()) motherPz = lambda ob1p4, ob2p4: (ob1p4.Pz() + ob2p4.Pz()) motherE = lambda ob1p4, ob2p4: (ob1p4.E() + ob2p4.E()) BoostP4 = lambda ob1p4, ob2p4: op._to.Construct( "ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<float> >", (motherPx(ob1p4, ob2p4), motherPy(ob1p4, ob2p4), motherPz(ob1p4, ob2p4), motherE(ob1p4, ob2p4))).result self.comp_cosThetaS = lambda ob1p4, ob2p4: op.abs( op.cos(op.deltaR(BoostP4(ob1p4, ob2p4), ob1p4))) # MET_LD # Equation 3 (page 33) of AN-2019/111 v13 # Similar to MET, but more robust against pileup jetSumPx = lambda jets: op.rng_sum(jets, lambda j: j.p4.Px()) jetSumPy = lambda jets: op.rng_sum(jets, lambda j: j.p4.Py()) lepSumPx = lambda leps: op.rng_sum(leps, lambda l: l.p4.Px()) lepSumPy = lambda leps: op.rng_sum(leps, lambda l: l.p4.Py()) self.MET_LD = lambda met, jets, leps: 0.6 * met.pt + 0.4 * op.sqrt( op.pow(jetSumPx(jets) + lepSumPx(leps), 2) + op.pow( jetSumPy(jets) + lepSumPy(leps), 2))
def plotMatching(contName, list_cont, list_sel, partName): plots = [] dr_plots = [] dr2_plots = [] ptrel_plots = [] TF_plots = [] for idx, (cont, sel) in enumerate(zip(list_cont, list_sel)): dr_plots.append( Plot.make1D(contName + str(idx) + "_deltaR", op.map(cont, lambda m: op.deltaR(m[0].p4, m[1].p4)), sel, EquidistantBinning(100, 0., 0.2), xTitle="#Delta R(%s_{gen},%s_{reco})" % (partName, partName))) dr2_plots.append( Plot.make1D(contName + str(idx) + "_deltaR2", op.map( cont, lambda m: op.pow(op.deltaR(m[0].p4, m[1].p4), 2)), sel, EquidistantBinning(100, 0., 0.04), xTitle="#Delta R^{2}(%s_{gen},%s_{reco})" % (partName, partName))) ptrel_plots.append( Plot.make1D( contName + str(idx) + "_deltaPtRel", op.map(cont, lambda m: (m[1].pt - m[0].pt) / m[1].pt), sel, EquidistantBinning(100, -2., 2.), xTitle="P_{T}(%s_{reco})-P_{T}(%s_{gen})/P_{T}(%s_{reco})" % (partName, partName, partName))) TF_plots.append( Plot.make2D(contName + str(idx) + "_TF", (op.map(cont, lambda m: m[0].p4.E()), op.map(cont, lambda m: m[1].p4.E() - m[0].p4.E())), sel, [ EquidistantBinning(100, 0., 500.), EquidistantBinning(400, -200., 200.) ], xTitle="E^{parton}(e^{-})", yTitle="#Delta E = E^{reco}(%s)-E^{parton}(%s)" % (partName, partName))) plots.append( SummedPlot(contName + "_deltaR", dr_plots, xTitle="#Delta R(%s_{gen},%s_{reco})" % (partName, partName))) plots.append( SummedPlot(contName + "_deltaR2", dr2_plots, xTitle="#Delta R^{2}(%s_{gen},%s_{reco})" % (partName, partName))) plots.append( SummedPlot(contName + "_deltaPtRel", ptrel_plots, xTitle="P_{T}(%s_{reco})-P_{T}(%s_{gen}/P_{T}(%s_{reco})" % (partName, partName, partName))) plots.append( SummedPlot(contName + "_TF", TF_plots, xTitle="#Delta E = E^{reco}(%s)-E^{patron}(%s)" % (partName, partName))) return plots