def comp_smin(self, lepconep4, met, jets, bjets, wjets): self.blank_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.)])) #vis = op.multiSwitch((op.rng_len(jets) >= 4, bjets[0].p4+bjets[1].p4+wjets[0].p4+wjets[1].p4+lep.p4), # (op.rng_len(jets) == 3, bjets[0].p4+bjets[1].p4+wjets[0].p4+lep.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.)))) vis = op.rng_sum( bjets, (lambda bj: bj.p4), start=self.blank_p4) + op.rng_sum( wjets, (lambda wj: wj.p4), start=self.blank_p4) + lepconep4 vis_pt = vis.Pt() vis_m = vis.M() vis_et = op.sqrt(op.pow(vis_m, 2) + op.pow(vis_pt, 2)) met_et = met.p4.E() return op.sqrt( op.pow(vis_m, 2) + 2 * (vis_et * met_et - (vis.Px() * met.p4.Px() + vis.Py() * met.p4.Py())))
def MakeExtraMETPlots(self, sel, lepton, met, uname, suffix): binScaling = 1 plots = [] for key in sel.keys(): plots.append( Plot.make1D("{0}_{1}_{2}_MET_pt".format(uname, key, suffix), met.pt, sel.get(key), EqB(60 // binScaling, 0., 600.), title="MET p_{T} [GeV]", plotopts=utils.getOpts(uname, **{"log-y": False}))) plots.append( Plot.make1D("{0}_{1}_{2}_MET_phi".format(uname, key, suffix), met.phi, sel.get(key), EqB(60 // binScaling, -3.1416, 3.1416), title="MET #phi", plotopts=utils.getOpts(uname, **{"log-y": False}))) plots.append( Plot.make1D("{0}_{1}_{2}_MET_eta".format(uname, key, suffix), met.phi, sel.get(key), EqB(60 // binScaling, -2.4, 2.4), title="MET #eta", plotopts=utils.getOpts(uname, **{"log-y": False}))) for i in range(2): plots.append( Plot.make1D( f"{uname}_{key}_{suffix}_MET_lep{i+1}_deltaPhi".format( uname=uname, key=key, suffix=suffix), op.Phi_mpi_pi(lepton[i].phi - met.phi), sel.get(key), EqB(60 // binScaling, -3.1416, 3.1416), title="#Delta #phi (lepton, MET)", plotopts=utils.getOpts(uname, **{"log-y": False}))) MT = op.sqrt( 2. * met.pt * lepton[i].p4.Pt() * (1. - op.cos(op.Phi_mpi_pi(met.phi - lepton[i].p4.Phi())))) plots.append( Plot.make1D(f"{uname}_{key}_{suffix}_MET_MT_lep{i+1}".format( uname=uname, key=key, suffix=suffix), MT, sel.get(key), EqB(60 // binScaling, 0., 600.), title="Lepton M_{T} [GeV]", plotopts=utils.getOpts(uname, **{"log-y": False}))) return plots
def findJPACategoryBoosted (self, selObj, lepton, muons, electrons, fatJets, jets, bJetsL, bJetsM, met, modelPathDict, event, HLL, nodeList, plot_yield=False): JPAfuncDict = {'f1':evaluateJPA_Hbb2Wj, 'f2':evaluateJPA_Hbb1Wj} JPAMaxScoreList = [] bestCombo_per_cat = [] combo2 = op.combine(jets, N=2, pred=lambda j1,j2 : j1.pt > j2.pt, samePred=lambda j1,j2 : j1.idx != j2.idx) fakeCombo2 = op.combine(jets, N=2, pred=lambda j1,j2 : j1.pt >= j2.pt, samePred=None) funckeys = [k for k in JPAfuncDict.keys()] for idx, func in enumerate(funckeys): node = nodeList[idx] modelpaths = modelPathDict.get(node) model = makeOddEvenEvaluator(event%2, modelpaths[1], modelpaths[0], mvaType="TMVA") lambdaFunc = lambda jetCombo : JPAfuncDict[func](lepton, muons, electrons, fatJets, jetCombo, bJetsL, bJetsM, met, model, HLL) if idx == 0: best = op.rng_max_element_by(combo2, lambdaFunc) maxScore = op.switch(best.idx != -1, best.idx.op.this.result.second, op.c_float(-1.)) else: best = op.rng_max_element_by(fakeCombo2, lambdaFunc) #best = op.rng_max_element_by(combo2, lambdaFunc) maxScore = best.idx.op.this.result.second #maxScore = op.switch(best.idx != -1, best.idx.op.this.result.second, op.c_float(-1.)) JPAMaxScoreList.append(op.pow((1.0 + op.sqrt((1 - maxScore)/(1 + maxScore))), -1)) #JPAMaxScoreList.append(maxScore) bestCombo_per_cat.append(best) evtCat = makeOddEvenEvaluator(event%2, modelPathDict.get('evCat')[1], modelPathDict.get('evCat')[0], mvaType="TMVA") JPAL2outList = evtCat(*JPAMaxScoreList) maxIdx = op.rng_max_element_index(JPAL2outList) newSelObj = copy(selObj) selObjJPAjetsIdxDict = {} for i, node in enumerate(nodeList): outSelObj = copy(newSelObj) outSelObj.selName += '%s'%node outSelObj.yieldTitle += " in %s node"%node outSelObj.refine(cut = [maxIdx == op.c_int(i)]) #if plot_yield: # outSelObj.makeYield(self.yieldPlots) if i < 2: selObjJPAjetsIdxDict[node] = [outSelObj, bestCombo_per_cat[i]] else: selObjJPAjetsIdxDict[node] = [outSelObj, None] return JPAMaxScoreList, JPAL2outList, selObjJPAjetsIdxDict
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 plots = [] # 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( "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("3lMT", mt3lPlots)) return plots
def makeMETPlots(sel, leptons, met, corrMET, uname): binScaling = 1 plots = [] plots.append( Plot.make1D(f"{uname}_MET_pt", met.pt, sel, EqBin(60 // binScaling, 0., 600.), title="MET p_{T} [GeV]", plotopts=utils.getOpts(uname, **{"log-y": False}))) plots.append( Plot.make1D(f"{uname}_MET_phi", met.phi, sel, EqBin(60 // binScaling, -3.1416, 3.1416), title="MET #phi", plotopts=utils.getOpts(uname, **{"log-y": False}))) for i in range(2): plots.append( Plot.make1D(f"{uname}_MET_lep{i+1}_deltaPhi", op.Phi_mpi_pi(leptons[i].phi - met.phi), sel, EqBin(60 // binScaling, -3.1416, 3.1416), title="#Delta #phi (lepton, MET)", plotopts=utils.getOpts(uname, **{"log-y": True}))) MT = op.sqrt( 2. * met.pt * leptons[i].p4.Pt() * (1. - op.cos(op.Phi_mpi_pi(met.phi - leptons[i].p4.Phi())))) plots.append( Plot.make1D(f"{uname}_MET_MT_lep{i+1}", MT, sel, EqBin(60 // binScaling, 0., 600.), title="Lepton M_{T} [GeV]", plotopts=utils.getOpts(uname, **{"log-y": False}))) 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 __init__(self, rawMET, pv, sample, era, isMC): if (era == '2016'): if isMC: xcorr = (0.195191, 0.170948) ycorr = (0.0311891, -0.787627) else: if '2016B' in sample: xcorr = (0.0478335, 0.108032) ycorr = (-0.125148, -0.355672) elif '2016C' in sample: xcorr = (0.0916985, -0.393247) ycorr = (-0.151445, -0.114491) elif '2016D' in sample: xcorr = (0.0581169, -0.567316) ycorr = (-0.147549, -0.403088) elif '2016E' in sample: xcorr = (0.065622, -0.536856) ycorr = (-0.188532, -0.495346) elif '2016F' in sample: xcorr = (0.0313322, -0.39866) ycorr = (-0.16081, -0.960177) elif '2016G' in sample: xcorr = (-0.040803, 0.290384) ycorr = (-0.0961935, -0.666096) else: xcorr = (-0.0330868, 0.209534) ycorr = (-0.141513, -0.816732) elif (era == '2017'): if isMC: xcorr = (0.217714, -0.493361) ycorr = (-0.177058, 0.336648) #these are the corrections for v2 MET recipe (currently recommended for 2017) else: if '2017B' in sample: xcorr = (0.19563, -1.51859) ycorr = (-0.306987, 1.84713) elif '2017C' in sample: xcorr = (0.161661, -0.589933) ycorr = (-0.233569, 0.995546) elif '2017D' in sample: xcorr = (0.180911, -1.23553) ycorr = (-0.240155, 1.27449) elif '2017E' in sample: xcorr = (0.149494, -0.901305) ycorr = (-0.178212, 0.535537) else: xcorr = (0.165154, -1.02018) ycorr = (-0.253794, -0.75776) elif (era == '2018'): if isMC: xcorr = (-0.296713, 0.141506) ycorr = (-0.115685, -0.0128193) else: if '2018A' in sample: xcorr = (-0.362865, 1.94505) ycorr = (-0.0709085, 0.307365) elif '2018B' in sample: xcorr = (-0.492083, 2.93552) ycorr = (-0.17874, 0.786844) elif '2018C' in sample: xcorr = (-0.521349, 1.44544) ycorr = (-0.118956, 1.96434) else: xcorr = (-0.531151, 1.37568) ycorr = (-0.0884639, 1.57089) METxcorr = xcorr[0] * op.min(pv.npvs, op.c_int(100)) + xcorr[1] METycorr = ycorr[0] * op.min(pv.npvs, op.c_int(100)) + ycorr[1] corrMETx = rawMET.pt * op.cos(rawMET.phi) + METxcorr corrMETy = rawMET.pt * op.sin(rawMET.phi) + METycorr atan = op.atan(corrMETy / corrMETx) self.pt = op.sqrt(corrMETx**2 + corrMETy**2) self.eta = op.c_float(0.) self.phi = op.multiSwitch((corrMETx > 0, atan), (corrMETy > 0, atan + math.pi), atan - math.pi) self.M = op.c_float(0.) #self.p4 = op.construct("ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<float> >", # (corrMETx,corrMETy,op.c_float(0.),op.sqrt(corrMETx**2 +corrMETy**2))) self.p4 = op.construct( "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<float> >", (self.pt, self.eta, self.phi, self.M))
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 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 findJPACategoryResolved (self, selObj, lepton, muons, electrons, jets, bJetsL, bJetsM, met, modelPathDict, event, HLL, nodeList, plot_yield=False): JPAfuncDict = {'f1':evaluateJPA_2b2Wj, 'f2':evaluateJPA_2b1Wj, 'f3':evaluateJPA_1b2Wj, 'f4':evaluateJPA_2b0Wj, 'f5':evaluateJPA_1b1Wj, 'f6':evaluateJPA_1b0Wj} JPAMaxScoreList = [] bestCombo_per_cat = [] combo2_1b0W_1Wj = op.combine(jets, N=2, samePred=lambda j1,j2 : j1.idx != j2.idx) combo2_2b0Wj = op.combine(jets, N=2, pred=lambda j1,j2 : j1.pt > j2.pt, samePred=lambda j1,j2 : j1.idx != j2.idx) combo3_1b2Wj = op.combine(jets, N=3, pred=lambda j1,j2,j3 : j2.pt > j3.pt, samePred=lambda j1,j2 : j1.idx != j2.idx) combo3_2b1Wj = op.combine(jets, N=3, pred=lambda j1,j2,j3 : j1.pt > j2.pt, samePred=lambda j1,j2 : j1.idx != j2.idx) combo4 = op.combine(jets, N=4, pred=lambda j1,j2,j3,j4 : op.AND(j1.pt > j2.pt, j3.pt > j4.pt), samePred=lambda j1,j2 : j1.idx != j2.idx) funckeys = [k for k in JPAfuncDict.keys()] for idx, func in enumerate(funckeys): node = nodeList[idx] modelpaths = modelPathDict.get(node) model = makeOddEvenEvaluator(event%2, modelpaths[1], modelpaths[0], mvaType="TMVA") lambdaFunc = lambda jetCombo : JPAfuncDict[func](lepton, muons, electrons, jets, jetCombo, bJetsL, bJetsM, met, model, HLL) if idx == 0: best = op.rng_max_element_by(combo4, lambdaFunc) maxScore = op.switch(best.idx != -1, best.idx.op.this.result.second, op.c_float(-1.)) #best.idx.op.this.canDefine=False elif idx == 1: best = op.rng_max_element_by(combo3_2b1Wj, lambdaFunc) ## hack: index of best is first in a pair, with the maximum value as second maxScore = best.idx.op.this.result.second elif idx == 2: best = op.rng_max_element_by(combo3_1b2Wj, lambdaFunc) ## hack: index of best is first in a pair, with the maximum value as second maxScore = best.idx.op.this.result.second elif idx == 3: best = op.rng_max_element_by(combo2_2b0Wj, lambdaFunc) ## hack: index of best is first in a pair, with the maximum value as second maxScore = best.idx.op.this.result.second elif idx == 4: best = op.rng_max_element_by(combo2_1b0W_1Wj, lambdaFunc) ## hack: index of best is first in a pair, with the maximum value as second maxScore = best.idx.op.this.result.second else: best = op.rng_max_element_by(combo2_1b0W_1Wj, lambdaFunc) ## hack: index of best is first in a pair, with the maximum value as second maxScore = best.idx.op.this.result.second JPAMaxScoreList.append(op.pow((1.0 + op.sqrt((1 - maxScore)/(1 + maxScore))), -1)) #JPAMaxScoreList.append(maxScore) bestCombo_per_cat.append(best) evtCat = makeOddEvenEvaluator(event%2, modelPathDict.get('evCat')[1], modelPathDict.get('evCat')[0], mvaType="TMVA") evtCatOutList = evtCat(*JPAMaxScoreList) maxIdx = op.rng_max_element_index(evtCatOutList) newSelObj = copy(selObj) selObjJPAjetsIdxDict = {} for i, node in enumerate(nodeList): outSelObj = copy(newSelObj) outSelObj.selName += '%s'%node outSelObj.yieldTitle += " in %s node"%node outSelObj.refine(cut = (maxIdx == i)) if i < 6: selObjJPAjetsIdxDict[node] = [outSelObj, bestCombo_per_cat[i]] else: selObjJPAjetsIdxDict[node] = [outSelObj, None] return JPAMaxScoreList, evtCatOutList, selObjJPAjetsIdxDict
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 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