def getAllLeptons(c, collVars=leptonVars, collection="LepGood"): n = int(getVarValue(c, 'n%s' % collection)) res = [getObjDict(c, '%s_' % collection, collVars, i) for i in range(n)] # recall intial index for i in range(n): res[i]['i%s' % collection] = i return res
def getJets(event, sample): jetVars = ['eta', 'pt', 'phi', 'btagCSV'] event.jets_sortbtag = [ getObjDict(event, 'jet_', jetVars, i) for i in range(int(getVarValue(event, 'nJetSelected'))) ] #nJetSelected event.jets_sortbtag.sort(key=lambda l: -l['btagCSV'])
def getSelectedJets(event, sample): jetVars = ['eta', 'pt', 'phi', 'btagCSV', 'DFbb', 'DFb', 'id'] event.selectedJets = [ getObjDict(event, 'jet_', jetVars, i) for i in range(int(getVarValue(event, 'njet'))) if (abs(event.jet_eta[i]) <= 2.4 and event.jet_pt[i] > 30 and event.jet_id[i]) ] #nJetSelected
def getLooseLeptonMult(event, sample): leptons = [ getObjDict(event, 'lep_', [ 'eta', 'pt', 'phi', 'charge', 'pdgId', 'sourceId', 'mediumMuonId' ], i) for i in range(len(event.lep_pt)) ] lepLoose = [ l for l in leptons if l['pt'] > 10 and ((l['mediumMuonId'] and abs(l['pdgId']) == 13) or abs(l['pdgId']) == 11) ] event.nLepLoose = len(lepLoose)
def getJets(event, sample): jetVars = ['eta', 'pt', 'phi', 'btagCSV', 'id'] event.jets = filter(lambda j: j['pt'] > 30 and j['id'], [ getObjDict(event, 'jet_', jetVars, i) for i in range(int(getVarValue(event, 'njet'))) ]) b_jets = filter(lambda j: isAnalysisJet(j) and isBJet(j), event.jets) leading_bjet = b_jets[0] if len(b_jets) > 0 else None if leading_bjet is not None: v_leading_bjet = ROOT.TLorentzVector() v_leading_bjet.SetPtEtaPhiM(leading_bjet['pt'], leading_bjet['eta'], leading_bjet['phi'], 0.) untagged_jets = filter(lambda j: not isBJet(j), event.jets) event.leading_untagged_jet = untagged_jets[0] if len( untagged_jets) > 0 else None if event.leading_untagged_jet is not None and leading_bjet is not None: v_leading_untagged_jet = ROOT.TLorentzVector() v_leading_untagged_jet.SetPtEtaPhiM(event.leading_untagged_jet['pt'], event.leading_untagged_jet['eta'], event.leading_untagged_jet['phi'], 0.) event.m_leadingUntagged_bJet = (v_leading_bjet + v_leading_untagged_jet).M() else: event.m_leadingUntagged_bJet = float('nan') untagged_jets.sort(key=lambda j: -abs(j['eta'])) event.mostForward_untagged_jet = untagged_jets[0] if len( untagged_jets) > 0 else None if event.mostForward_untagged_jet is not None and leading_bjet is not None: v_mostForward_untagged_jet = ROOT.TLorentzVector() v_mostForward_untagged_jet.SetPtEtaPhiM( event.mostForward_untagged_jet['pt'], event.mostForward_untagged_jet['eta'], event.mostForward_untagged_jet['phi'], 0.) event.m_mostForwardUntagged_bJet = (v_leading_bjet + v_mostForward_untagged_jet).M() else: event.m_mostForwardUntagged_bJet = float('nan') event.jets = filter(isAnalysisJet, event.jets)
def _estimate(self, region, channel, setup): if not setup.nonprompt: raise (NotImplementedError, "Need a nonprompt setup") ''' Concrete implementation of abstract method 'estimate' as defined in Systematic ''' logger.info("Prediction for %s channel %s" % (self.name, channel)) if channel.name == 'all': # estimate fake contribution from events with at least three loose leptons, and less than 3 tight leptons # take loose leptons with same pT requirements like analysis leptons tmpSample = self.sample variables = map(TreeVariable.fromString, [ "run/I", "lumi/I", "evt/I", "Z_pt/F", "cosThetaStar/F", "weight/F", "met_pt/F", "Z_mass/F", "nJetSelected/I", "nBTag/I", 'Z_l1_index/I', 'Z_l2_index/I', 'nonZ_l1_index/I', 'nonZ_l2_index/I', "nLeptons_FO_3l/I", "nLeptons_tight_3l/I", "nLeptons_tight_4l/I" ]) if not self.sample.isData: logger.info("Adding weights to be read.") variables += map( TreeVariable.fromString, ['reweightPU36fb/F', 'reweightBTagDeepCSV_SF/F']) variables += [ VectorTreeVariable.fromString( 'lep[pt/F,ptCorr/F,eta/F,phi/F,FO_3l/I,tight_3l/I,FO_SS/I,tight_SS/I,jetPtRatiov2/F,pdgId/I]' ) ] tmpSample.setSelectionString([ setup.preselection(self.dataMC, nElectrons=channel.nE, nMuons=channel.nM)['cut'], region.cutString() ]) reader = tmpSample.treeReader(allBranchesActive=True, variables=variables) reader.start() fakeYield = u_float(0) nEvents = u_float(tmpSample.getYieldFromDraw()) logger.info("Runing over %s events.", nEvents.val) while reader.run(): nLep = len([l for l in reader.event.lep_pt if l > 0]) lep = [ getObjDict(reader.event, "lep" + '_', [ "pt", "ptCorr", "eta", "phi", "FO_3l", "FO_SS", "tight_3l", "tight_SS", "pdgId", "jetPtRatiov2" ], i) for i in range(nLep) ] # get the relevant leptons lep = [l for l in lep if l[setup.leptonId]] # get tight and loose separately looseNotTight = [l for l in lep if not l[setup.tight_ID]] tight = [l for l in lep if l[setup.tight_ID]] nLooseNotTight = len(looseNotTight) nTight = len(tight) # Really get ALL possible combinations. allCombinations = itertools.combinations( tight + looseNotTight, setup.nLeptons) for comb in allCombinations: FR = 1. nLooseNotTight = 0 for l in comb: if l[setup.tight_ID]: continue else: if abs(l['pdgId']) == 11: FRmap = self.elMap elif abs(l['pdgId']) == 13: FRmap = self.muMap else: raise NotImplementedError # we run out of stats in data at higher pt, hence we cut at a lower value ptCut = 45. if self.sample.isData else 99. ptCorrected = l[ 'ptCorr'] if l['ptCorr'] < ptCut else (ptCut - 1) FR_from_map = FRmap.GetBinContent( FRmap.FindBin(ptCorrected, abs(l['eta']))) if self.sample.isData: FR *= FR_from_map / (1 - FR_from_map) else: FR *= FR_from_map nLooseNotTight += 1 FR *= (-1)**(nLooseNotTight + 1) allweights = [setup.sys['weight']] + setup.sys['reweight'] if self.sample.isData: weight = 1 else: weights = [ getattr(reader.event, w) for w in allweights ] weight = reduce(mul, weights, 1) fakeYield += (weight * FR) # apply the statistical uncertainty to the result result = u_float(0.) if nEvents.val == 0 else u_float( fakeYield, (nEvents.sigma / nEvents.val) * fakeYield) return result if self.sample.isData else (result * setup.lumi / 1000.)
def extra_observables(event, sample): # get the negative-charge lepton from Z l_m_index = event.Z_l1_index if event.lep_pdgId[ event.Z_l1_index] > 0 else event.Z_l2_index # beta and gamma from Z gamma = sqrt(1 + event.Z_pt**2 / event.Z_mass**2 * cosh(event.Z_eta)**2) beta = sqrt(1 - 1 / gamma**2) # Z boson and l3 (convinience) Z_3D = ROOT.TVector3(event.Z_pt * cos(event.Z_phi), event.Z_pt * sin(event.Z_phi), event.Z_pt * sinh(event.Z_eta)) l_m_3D = ROOT.TVector3( event.lep_pt[l_m_index] * cos(event.lep_phi[l_m_index]), event.lep_pt[l_m_index] * sin(event.lep_phi[l_m_index]), event.lep_pt[l_m_index] * sinh(event.lep_eta[l_m_index])) # cos(theta) ... cos(Z, l^-) in lab frame cosTheta = Z_3D * l_m_3D / (sqrt(Z_3D * Z_3D) * sqrt(l_m_3D * l_m_3D)) event.cosThetaStar = (-beta + cosTheta) / (1 - beta * cosTheta) l3_3D = ROOT.TVector3( event.lep_pt[event.nonZ_l1_index] * cos(event.lep_phi[event.nonZ_l1_index]), event.lep_pt[event.nonZ_l1_index] * sin(event.lep_phi[event.nonZ_l1_index]), event.lep_pt[event.nonZ_l1_index] * sinh(event.lep_eta[event.nonZ_l1_index])) l3_pt = event.lep_pt[event.nonZ_l1_index] l3_phi = event.lep_phi[event.nonZ_l1_index] l3_eta = event.lep_eta[event.nonZ_l1_index] Z_2D = ROOT.TVector2(Z_3D[0], Z_3D[1]) n_Z_2D = ROOT.TVector2(cos(event.Z_phi), sin(event.Z_phi)) n_orth_Z_2D = ROOT.TVector2(-sin(event.Z_phi), cos(event.Z_phi)) l3_2D = ROOT.TVector2(l3_3D[0], l3_3D[1]) # me_x,y met_2D = ROOT.TVector2(event.met_pt * cos(event.met_phi), event.met_pt * sin(event.met_phi)) # get jets jetVars = ['eta', 'pt', 'phi', 'btagCSV', 'id'] jets = filter(isAnalysisJet, [ getObjDict(event, 'jet_', jetVars, i) for i in range(int(getVarValue(event, 'njet'))) ]) jets.sort(key=lambda l: -l['pt']) bJets = filter( lambda j: isBJet(j, tagger='CSVv2') and abs(j['eta']) <= 2.4, jets) nonBJets = filter( lambda j: not (isBJet(j, tagger='CSVv2') and abs(j['eta']) <= 2.4), jets) # take highest-pT b-jet, supplement by non-bjets if there are less than two bj0, bj1 = (bJets + nonBJets)[:2] bj0_3D = ROOT.TVector3(bj0['pt'] * cos(bj0['phi']), bj0['pt'] * sin(bj0['phi']), bj0['pt'] * sinh(bj0['eta'])) bj1_3D = ROOT.TVector3(bj1['pt'] * cos(bj1['phi']), bj1['pt'] * sin(bj1['phi']), bj1['pt'] * sinh(bj1['eta'])) bj0_2D = ROOT.TVector2(bj0_3D[0], bj0_3D[1]) bj1_2D = ROOT.TVector2(bj1_3D[0], bj1_3D[1]) # resolve pairing ambiguity of bjets to top candidates by maximising the resulting sum-pT (the miracle of M3) if (bj0_2D + l3_2D + met_2D).Mod2() > (bj1_2D + l3_2D + met_2D).Mod2(): blep, bhad = bj0, bj1 blep_2D, bhad_2D = bj0_2D, bj1_2D blep_3D, bhad_3D = bj0_3D, bj1_3D else: blep, bhad = bj1, bj0 blep_2D, bhad_2D = bj1_2D, bj0_2D blep_3D, bhad_3D = bj1_3D, bj0_3D event.blep_pt = blep['pt'] # ST observables event.ST = l3_pt + event.met_pt # traditional (1l SUS) event.St = l3_pt + event.met_pt + event.blep_pt # scalar sum pt of the leptonic top candidate # MT observables event.mT = sqrt(2 * event.met_pt * l3_pt * (1 - cos(event.met_phi - l3_phi)) ) # transverse mass of leptonic W candidate event.mt = sqrt( 2*event.met_pt*l3_pt*(1 - cos(event.met_phi - l3_phi)) \ + 2*blep['pt']*l3_pt*(cosh(blep['eta'] - l3_eta)-cos(blep['phi'] - l3_phi)) + 2*event.met_pt*blep['pt']*(1-cos(event.met_phi - blep['phi'])) ) # transverse mass of the leptonic top # variables with 2D vectors for fname, f in [\ #[ 'dPhiZ', lambda vec: ROOT.TVector2.DeltaPhi( vec, Z_2D )], [ 'absDPhiZ', lambda vec: abs(ROOT.TVector2.DeltaPhi( vec, Z_2D ))], [ 'projZ', lambda vec: vec* n_Z_2D ], #[ 'dotZ', lambda vec: vec.Dot( Z_2D ) )], [ 'projorthZ',lambda vec: vec*n_orth_Z_2D ], ]: for vname, v in [ ["met", met_2D], ["met_blep", met_2D + blep_2D], ["met_l3", met_2D + l3_2D], ["l3", l3_2D], ["blep", blep_2D], ["l3_blep", l3_2D + blep_2D], ["met_l3_blep", l3_2D + blep_2D + met_2D], ]: #varname = "%s_%s"%( fname, vname ) setattr(event, "%s_%s" % (fname, vname), f(v)) # variables with 3D vectors for fname, f in [ ['dRZ', lambda vec: ROOT.TVector3.DeltaR(vec, Z_3D)], ]: for vname, v in [ ["l3", l3_3D], ["blep", blep_3D], ["l3_blep", l3_3D + blep_3D], ]: #varname = "%s_%s"%( fname, vname ) setattr(event, "%s_%s" % (fname, vname), f(v))
def getGenLeps(c): return [ getObjDict(c, 'genLep_', ['eta', 'pt', 'phi', 'charge', 'pdgId', 'sourceId'], i) for i in range(int(getVarValue(c, 'ngenLep'))) ]
def getTaus(c, collVars=tauVars): return [ getObjDict(c, 'TauGood_', collVars, i) for i in range(int(getVarValue(c, 'nTauGood'))) ]
def getAllLeptons(c, collVars=leptonVars, collection="LepGood"): return [ getObjDict(c, '%s_' % collection, collVars, i) for i in range(int(getVarValue(c, 'n%s' % collection))) ]
def getJets(c, jetVars=jetVars, jetColl="Jet"): return [ getObjDict(c, jetColl + '_', jetVars, i) for i in range(int(getVarValue(c, 'n' + jetColl))) ]
def getGenPartsAll(c, collection="genPartAll", genVars=genVars): return [ getObjDict(c, '%s_' % collection, genVars, i) for i in range(getattr(c, 'n%s' % collection)) ]
def getGenParts(c): return [ getObjDict(c, 'GenPart_', [ 'eta', 'pt', 'phi', 'charge', 'pdgId', 'motherId', 'grandmotherId' ], i) for i in range(int(getVarValue(c, 'nGenPart'))) ]
hists["lep_pt_trail"] = sample.get1DHistoFromDraw("lep_pt[2]", selectionString=sel_string, binning=[10, 0, 100], addOverFlowBin='upper', weightString=weight_central) # Run the tree reader for cases with more complicated plots hists["lep_pt_trail"].Reset() sample.setSelectionString(sel_string) reader = sample.treeReader(variables=variables) reader.start() while reader.run(): nLep = len([l for l in reader.event.lep_pt if l > 0]) lep = [ getObjDict(reader.event, "lep" + '_', [ "pt", "ptCorr", "eta", "phi", "FO_3l", "FO_SS", "tight_3l", "tight_SS", "pdgId", "jetPtRatiov2" ], i) for i in range(nLep) ] # get the relevant leptons lep = [l for l in lep if l[tight_ID]] if len(lep) != nLeptons: print "bug" allweights = ["weight", "reweightPU36fb", "reweightBTagDeepCSV_SF"] if sample.isData: weight = 1 else: weights = [getattr(reader.event, w) for w in allweights] weight = reduce(mul, weights, 1)
def getAllJets(event, sample): jetVars = ['eta', 'pt', 'btagCSV'] event.allJets = [ getObjDict(event, 'jet_', jetVars, i) for i in range(int(getVarValue(event, 'njet'))) ]
def getPhotons(c, collVars=photonVars, idLevel='loose'): return [ getObjDict(c, 'gamma_', collVars, i) for i in range(int(getVarValue(c, 'ngamma'))) ]
def extra_observables( event, sample ): G = {'pt':event.photon_pt, 'eta':event.photon_eta, 'phi':event.photon_phi} G_2D = ROOT.TVector2( event.photon_pt*cos(event.photon_phi), event.photon_pt*sin(event.photon_phi) ) n_G_2D = ROOT.TVector2( cos(event.photon_phi), sin(event.photon_phi) ) #G_3D = ROOT.TVector2( event.photon_pt*cos(event.photon_phi), event.photon_pt*sin(event.photon_phi) ) #n_G_3D = ROOT.TVector2( cos(event.photon_phi), sin(event.photon_phi) ) # me_x,y met_2D = ROOT.TVector2( event.met_pt*cos(event.met_phi), event.met_pt*sin(event.met_phi) ) event.deltaPhi_G_MET = deltaPhi( G['phi'], event.met_phi ) event.deltaPhi_ll = deltaPhi(event.lep_phi[0], event.lep_phi[1]) event.deltaR_ll = deltaR({'phi':event.lep_phi[0], 'eta':event.lep_eta[0]}, {'phi':event.lep_phi[1], 'eta':event.lep_eta[1]}) ## get jets jetVars = ['eta','pt','phi','btagCSV','id'] jets = filter( isAnalysisJet, [getObjDict(event, 'jet_', jetVars, i) for i in range(int(getVarValue(event, 'njet')))] ) jets.sort( key = lambda l:-l['pt'] ) bJets = filter(lambda j: isBJet(j, tagger = 'CSVv2') and abs(j['eta'])<=2.4, jets ) nonBJets = filter(lambda j: not ( isBJet(j, tagger = 'CSVv2') and abs(j['eta'])<=2.4 ), jets) # take highest-pT b-jet, supplement by non-bjets if there are less than two bj1, bj2 = (bJets+nonBJets)[:2] l_bj1 = ROOT.TLorentzVector() l_bj1.SetPtEtaPhiM( bj1['pt'], bj1['eta'], bj1['phi'], 0 ) l_bj2 = ROOT.TLorentzVector() l_bj2.SetPtEtaPhiM( bj2['pt'], bj2['eta'], bj2['phi'], 0 ) # leptons l_lep1 = ROOT.TLorentzVector() l_lep1.SetPtEtaPhiM( event.lep_pt[0], event.lep_eta[0], event.lep_phi[0], 0 ) lep1 = {'pt':event.lep_pt[0], 'eta':event.lep_eta[0], 'phi':event.lep_phi[0]} l_lep2 = ROOT.TLorentzVector() l_lep2.SetPtEtaPhiM( event.lep_pt[1], event.lep_eta[1], event.lep_phi[1], 0 ) lep2 = {'pt':event.lep_pt[1], 'eta':event.lep_eta[1], 'phi':event.lep_phi[1]} # resolve pairing ambiguity max1 = max([(l_lep1 + l_bj1).M(), (l_lep2 + l_bj2).M()]) max2 = max([(l_lep1 + l_bj2).M(), (l_lep2 + l_bj1).M()]) if max1<max2: #Choose pairing with smaller invariant mass pass else: # switch bj1, bj2 = bj2, bj1 l_bj1, l_bj2 = l_bj2, l_bj1 event.M_lb_max = max(max1, max2) event.M_lb_min = min(max1, max2) # G & leps dPhi_G_l1 = deltaPhi( G['phi'], lep1['phi'] ) dPhi_G_l2 = deltaPhi( G['phi'], lep2['phi'] ) event.dPhi_G_l_max = max(dPhi_G_l1, dPhi_G_l2) event.dPhi_G_l_min = min(dPhi_G_l1, dPhi_G_l2) dR_G_l1 = deltaR( G, lep1 ) dR_G_l2 = deltaR( G, lep2 ) event.dR_G_l_max = max(dR_G_l1, dR_G_l2) event.dR_G_l_min = min(dR_G_l1, dR_G_l2) return