def makeLeps(event, sample): ''' Add a list of filtered leptons to the event ''' # load leps event.leps = getCollection(event, 'GenLep', ['pt', 'eta', 'phi', 'pdgId', 'motherPdgId'], 'nGenLep') # filter, pre-selection requires 3 leptons (no default leptons necessary) event.leps = list(filter(lambda l: isGoodGenLepton(l), event.leps)) # Cross-cleaning: remove leptons that overlap with a jet within 0.4 event.leps = list( filter(lambda l: min([deltaR(l, j) for j in event.jets] + [999]) > 0.4, event.leps)) # sort event.leps = sorted(event.leps, key=lambda l: -l['pt']) # Add extra vectors for p in event.leps: addTransverseVector(p) addTLorentzVector(p) # 2l event.l0, event.l1 = (event.leps + [NanLepton(), NanLepton()])[:2] # We may loose some events by cross-cleaning or by thresholds. event.passing_2lep = len( event.leps) >= 2 and event.l0['pdgId'] * event.l1['pdgId'] > 0.
def makeLeps(event, sample): ''' Add a list of filtered leptons to the event ''' # load leps event.leps = getCollection(event, 'GenLep', ['pt', 'eta', 'phi', 'pdgId', 'motherPdgId'], 'nGenLep') # filter, pre-selection requires 3 leptons (no default leptons necessary) event.leps = list(filter(lambda l: isGoodGenLepton(l), event.leps)) # Cross-cleaning: remove leptons that overlap with a jet within 0.4 event.leps = list( filter(lambda l: min([deltaR(l, j) for j in event.jets] + [999]) > 0.4, event.leps)) # sort event.leps = sorted(event.leps, key=lambda l: -l['pt']) # Add extra vectors for p in event.leps: addTransverseVector(p) addTLorentzVector(p) # find leptons from Z event.lepsFromZ = list(filter(lambda j: j['motherPdgId'] == 23, event.leps)) event.foundZ = len(event.lepsFromZ) == 2 and event.lepsFromZ[0][ 'pdgId'] * event.lepsFromZ[1]['pdgId'] < 0 and abs( event.lepsFromZ[0]['pdgId']) == abs(event.lepsFromZ[1]['pdgId']) event.Z_deltaPhi_ll = deltaPhi( event.lepsFromZ[0]['phi'], event.lepsFromZ[1]['phi']) if event.foundZ else float('nan') event.Z_deltaR_ll = deltaR( *event.lepsFromZ) if event.foundZ else float('nan') # find leptons that are NOT from Z event.lepsNotFromZ = list( filter(lambda j: j['motherPdgId'] != 23, event.leps)) # We may loose some events by cross-cleaning or by thresholds. event.passing_4lep = event.foundZ and len( event.lepsNotFromZ) >= 2 and event.lepsNotFromZ[0][ 'pdgId'] * event.lepsNotFromZ[1]['pdgId'] < 0. # Add default lepton if leptons got filtered event.lepsNotFromZ += [NanLepton(), NanLepton()] # Define non-Z leptons event.l0, event.l1 = event.lepsNotFromZ[:2]
def filler(event): event.lumiweight1fb = lumiweight1fb if not args.HEPMC: event.run, event.lumi, event.evt = fwliteReader.evt if fwliteReader.position % 100 == 0: logger.info("At event %i/%i", fwliteReader.position, fwliteReader.nEvents) if args.addReweights: event.nrw = weightInfo.nid lhe_weights = fwliteReader.products['lhe'].weights() weights = [] param_points = [] for weight in lhe_weights: # Store nominal weight (First position!) if weight.id == 'rwgt_1': event.rw_nominal = weight.wgt if not weight.id in weightInfo.id: continue pos = weightInfo.data[weight.id] event.rw_w[pos] = weight.wgt weights.append(weight.wgt) interpreted_weight = interpret_weight(weight.id) for var in weightInfo.variables: getattr(event, "rw_" + var)[pos] = interpreted_weight[var] # weight data for interpolation if not hyperPoly.initialized: param_points.append( tuple(interpreted_weight[var] for var in weightInfo.variables)) # get list of values of ref point in specific order ref_point_coordinates = [ weightInfo.ref_point_coordinates[var] for var in weightInfo.variables ] # Initialize with Reference Point if not hyperPoly.initialized: hyperPoly.initialize(param_points, ref_point_coordinates) coeff = hyperPoly.get_parametrization(weights) # = HyperPoly(weight_data, args.interpolationOrder) event.np = hyperPoly.ndof event.chi2_ndof = hyperPoly.chi2_ndof(coeff, weights) #logger.debug( "chi2_ndof %f coeff %r", event.chi2_ndof, coeff ) if event.chi2_ndof > 10**-6: logger.warning("chi2_ndof is large: %f", event.chi2_ndof) for n in xrange(hyperPoly.ndof): event.p_C[n] = coeff[n] # lumi weight / w0 event.ref_lumiweight1fb = event.lumiweight1fb / coeff[0] if not args.HEPMC: # All gen particles gp = fwliteReader.products['gp'] # for searching search = GenSearch(gp) # find heavy objects before they decay genTops = map( lambda t: {var: getattr(t, var)() for var in top_varnames}, filter(lambda p: abs(p.pdgId()) == 6 and search.isLast(p), gp)) genTops.sort(key=lambda p: -p['pt']) fill_vector_collection(event, "genTop", top_varnames, genTops) # generated Z's genZs = filter( lambda p: abs(p.pdgId()) == 23 and search.isLast(p) and abs( p.daughter(0).pdgId()) in [11, 13], gp) genZs.sort(key=lambda p: -p.pt()) if len(genZs) > 0: genZ = genZs[0] for var in boson_read_varnames: setattr(event, "genZ_" + var, getattr(genZ, var)()) else: genZ = None event.signalZ = 0 #ttZ with Z from gluon or top if genZ is not None: if abs(search.ascend(genZ).mother(0).pdgId()) in [6, 21]: event.signalZ = 1 #ttZ with Z from gluon or top d1, d2 = genZ.daughter(0), genZ.daughter(1) if d1.pdgId() > 0: lm, lp = d1, d2 else: lm, lp = d2, d1 event.genZ_daughterPdg = lm.pdgId() event.genZ_cosThetaStar = cosThetaStar(genZ.mass(), genZ.pt(), genZ.eta(), genZ.phi(), lm.pt(), lm.eta(), lm.phi()) # generated W's genWs = filter(lambda p: abs(p.pdgId()) == 24 and search.isLast(p), gp) genWs.sort(key=lambda p: -p.pt()) # W can't have a top-mother - We're looking for the extra boson (there is always an extra boson) genWs = filter(lambda p: abs(search.ascend(p).mother(0).pdgId()) != 6, genWs) if len(genWs) > 0: genW = genWs[0] for var in boson_read_varnames: setattr(event, "genW_" + var, getattr(genW, var)()) else: genW = None if genW is not None: d1, d2 = genW.daughter(0), genW.daughter(1) if abs(d1.pdgId()) in [11, 13, 15]: lep, neu = d1, d2 else: lep, neu = d2, d1 event.genW_daughterPdg = lep.pdgId() ## this def should only be called in debug mode # def printTopMothers(): # genTopCheck = [ (search.ascend(l), l, search.ancestry( search.ascend(l) )) for l in filter( lambda p:abs(p.pdgId())==6, gp) ] # # print genTopCheck # genTopCheck.sort( key = lambda p: -p[1].pt() ) # if len(genTopCheck) > 0: # topPdg_ids = filter( lambda p:p!=2212, [abs(particle.pdgId()) for particle in genTopCheck[0][2]]) # print 'TOP 1' # print topPdg_ids # previous = genTopCheck[0][0].mother(1) # print 'first', genTopCheck[0][0].pdgId() # for i, pdg in enumerate(topPdg_ids): # try: # print 'mother', i, previous.pdgId() # print 'mothers', i, [p.pdgId() for p in search.ancestry( previous )] # previous = previous.mother(0) # except Exception as val: # print val # break # if len(genTopCheck) > 1: # topPdg_ids = filter( lambda p:p!=2212, [abs(particle.pdgId()) for particle in genTopCheck[1][2]]) # print 'TOP 2' # print topPdg_ids # previous = genTopCheck[1][0].mother(1) # print 'first', genTopCheck[1][0].pdgId() # for i, pdg in enumerate(topPdg_ids): # try: # print 'mother', i, previous.pdgId() # print 'mothers', i, [p.pdgId() for p in search.ancestry( previous )] # previous = previous.mother(0) # except Exception as val: # print val # break # MET genMet = { 'pt': fwliteReader.products['genMET'][0].pt(), 'phi': fwliteReader.products['genMET'][0].phi() } event.genMet_pt = genMet['pt'] event.genMet_phi = genMet['phi'] # for ttgamma and tt events, categorize events: # a1) ttgamma vertex, gamma from t/g, isolated, must be in ttgamma sample = ttgamma signal (photonSignal == 1) # -> gamma isolated # -> gamma with only tops/gluons in ancestry # a2) ttgamma, gamma from ISR, must be in ttgamma sample = tt ISR bg (photonISR == 1) # -> gamma isolated # -> gamma with no top in ancestry # -> gamma with only gluons and light quarks in ancestry # -> direct gamma mother != gluon!!! (this is a1) # b) tt + isolated gamma from W, l, tau, must be in tt sample = ttgamma (W,l,tau) bg (photonLep == 1) # -> gamma isolated # -> gamma with direct abs mother being 11, 13, 15 or 24 # c1) tt + non isolated gamma from anything including mesons = tt bg (ttBg == 1) # -> gamma non isolated or meson in ancestry # c2) tt + isolated gamma from bottom quark (from t decay) or jets (from W) = tt bottom bg (ttBg == 1) # -> gamma isolated from b or j (from t/W decay) # ATTENTION: gammas from bottoms with off-shell tops where the # top decay is done by pythia are currently labeled as ISR! # However this case is currently not simulated in any sample # d) tt + gamma fake = ttgamma fake (photonFake == 1) # -> everything else does not contain a photon # -> if it still passes selection: it is a photon fake genPhotonsSignalCheck = [ (search.ascend(l), l, search.ancestry(search.ascend(l))) for l in filter( lambda p: abs(p.pdgId()) == 22 and p.pt() > 10 and abs(p.eta()) < 2.5 and search.isLast(p) and p.status() == 1, gp) ] genPhotonsSignalCheck.sort(key=lambda p: -p[1].pt()) photonSignal = 0 #a1 photonISR = 0 #a2 photonLep = 0 #b ttBg = 0 #c1 photonJets = 0 #c2 photonFake = 0 #d if len(genPhotonsSignalCheck) > 0: # check hardest photon with pT>13 and abs(eta)<2.5 first, last, ancestry = genPhotonsSignalCheck[0] # get abs pdgIDs of ancestry pdg_ids = filter(lambda p: p != 2212, [abs(particle.pdgId()) for particle in ancestry]) # check if particles are close by close_particles = filter( lambda p: p != last and p.pt() > 5 and deltaR2( { 'phi': last.phi(), 'eta': last.eta() }, { 'phi': p.phi(), 'eta': p.eta() }) < 0.2**2, search.final_state_particles_no_neutrinos) # print 'mothers pdg', pdg_ids # print 'close', [p.pdgId() for p in close_particles] # print 'first mother pdg', first.mother(0).pdgId() # if len(pdg_ids) < 999: # previous = first.mother(0) # for i, pdg in enumerate(pdg_ids): # try: # print 'mother', i, previous.pdgId() # previous = previous.mother(0) # except Exception as val: # print val # break # deside the categories if max(pdg_ids) > 100 or len(close_particles) != 0: #photon with meson in ancestry or non isolated -> cat c1) ttBg = 1 elif abs(first.mother(0).pdgId()) in [11, 13, 15, 24]: #isolated photon with W, l or tau direct mother -> cat b) photonLep = 1 # elif all( [ p in [ 6, 21 ] for p in pdg_ids ] ) or abs(first.mother(0).pdgId()) == 21: # not working for photons from top, as the gluons can come from light quarks elif abs(first.mother(0).pdgId()) in [6, 21]: #isolated photon with photon from top or gluon -> cat a1) photonSignal = 1 # printTopMothers() elif all([p in [1, 2, 3, 4, 5, 21] for p in pdg_ids]): #isolated photon with photon ancestry only containing light quarks or gluons (ISR) -> cat a1) photonISR = 1 else: #isolated gammas from bottoms originating from the top decay or jets from W -> cat c2) photonJets = 1 else: # if events with photonFake == 1 pass selection: fake gamma -> cat d) photonFake = 1 # if all flags are 0, it is an isolated gamma from a process I havn't thought of! # should not be there! - check! event.signalPhoton = photonSignal event.isrPhoton = photonISR event.lepPhoton = photonLep event.nonIsoPhoton = ttBg event.jetPhoton = photonJets event.fakePhoton = photonFake # gen photons: particle-level isolated gen photons genPhotons = [(search.ascend(l), l) for l in filter( lambda p: abs(p.pdgId()) == 22 and p.pt() > 15 and search.isLast(p) and p.status() == 1, gp)] genPhotons.sort(key=lambda p: -p[1].pt()) genPhotons_ = [] for first, last in genPhotons[:100]: mother_pdgId = first.mother( 0).pdgId() if first.numberOfMothers() > 0 else 0 genPhoton_ = { var: getattr(last, var)() for var in boson_read_varnames } # kinematic photon selection if not isGoodGenPhoton(genPhoton_): continue genPhoton_['motherPdgId'] = mother_pdgId genPhoton_['status'] = last.status() close_particles = filter( lambda p: p != last and deltaR2( { 'phi': last.phi(), 'eta': last.eta() }, { 'phi': p.phi(), 'eta': p.eta() }) < 0.4**2, search.final_state_particles_no_neutrinos) genPhoton_['relIso04'] = sum([p.pt() for p in close_particles], 0) / last.pt() # require isolation if genPhoton_['relIso04'] < 0.4: genPhotons_.append(genPhoton_) # genLeptons: prompt gen-leptons genLeptons = [(search.ascend(l), l) for l in filter( lambda p: abs(p.pdgId()) in [11, 13] and search.isLast(p) and p.pt( ) >= 0 and p.status() == 1, gp)] promptGenLeps = [] allGenLeps = [] for first, last in genLeptons: mother = first.mother(0) if first.numberOfMothers() > 0 else None if mother is not None: mother_pdgId = mother.pdgId() mother_ascend = search.ascend(mother) grandmother = mother_ascend.mother( 0) if mother.numberOfMothers() > 0 else None grandmother_pdgId = grandmother.pdgId( ) if grandmother is not None else 0 else: mother_pdgId = 0 grandmother_pdgId = 0 genLep = {var: getattr(last, var)() for var in lep_varnames} genLep['motherPdgId'] = mother_pdgId genLep['grandmotherPdgId'] = grandmother_pdgId allGenLeps.append(genLep) if abs(genLep['motherPdgId']) in [11, 13, 15, 23, 24, 25]: promptGenLeps.append(genLep) # filter gen leptons promptGenLeps = list( filter(lambda l: isGoodGenLepton(l), promptGenLeps)) promptGenLeps.sort(key=lambda p: -p['pt']) addIndex(promptGenLeps) ## removing photons in dR cone leptons (radiation photons) for genPhoton in genPhotons_: genPhoton['minLeptonDR'] = min( [999] + [deltaR(genPhoton, l) for l in allGenLeps]) genPhotons_ = list( filter(lambda g: g['minLeptonDR'] > 0.4, genPhotons_)) addIndex(genPhotons_) # jets fwlite_genJets = filter(genJetId, fwliteReader.products['genJets']) genJets = map( lambda t: {var: getattr(t, var)() for var in jet_read_varnames}, filter(lambda j: j.pt() > 30, fwlite_genJets)) # filter genJets genJets = list(filter(lambda j: isGoodGenJet(j), genJets)) # cleaning of jets with isolated photons genJets = list( filter( lambda j: min([999] + [deltaR2(j, p) for p in genPhotons_]) > 0.4**2, genJets)) # store minimum DR to jets for genPhoton in genPhotons_: genPhoton['minJetDR'] = min( [999] + [deltaR(genPhoton, j) for j in genJets]) # find b's from tops: b_partons = [ b for b in filter( lambda p: abs(p.pdgId()) == 5 and p.numberOfMothers() == 1 and abs(p.mother(0).pdgId()) == 6, gp) ] # store if gen-jet is DR matched to a B parton for genJet in genJets: genJet['matchBParton'] = (min([999] + [ deltaR2(genJet, { 'eta': b.eta(), 'phi': b.phi() }) for b in b_partons ]) < 0.2**2) genJets = filter( lambda j: (min( [999] + [deltaR2(j, l) for l in promptGenLeps if l['pt'] > 10]) > 0.3**2), genJets) genJets.sort(key=lambda p: -p['pt']) addIndex(genJets) # gen b jets trueBjets = list(filter(lambda j: j['matchBParton'], genJets)) trueNonBjets = list(filter(lambda j: not j['matchBParton'], genJets)) # Mimick b reconstruction ( if the trailing b fails acceptance, we supplement with the leading non-b jet ) genBj0, genBj1 = (trueBjets + trueNonBjets + [None, None])[:2] if genBj0: fill_vector(event, "genBj0", jet_write_varnames, genBj0) if genBj1: fill_vector(event, "genBj1", jet_write_varnames, genBj1) # reco-bjet/leading lepton association if len(promptGenLeps) > 0 and genBj0 and genBj1: if vecSumPt(genBj0, promptGenLeps[0], genMet) > vecSumPt( genBj1, promptGenLeps[0], genMet): event.genBjLeadlep_index, event.genBjLeadhad_index = genBj0[ 'index'], genBj1['index'] else: event.genBjLeadlep_index, event.genBjLeadhad_index = genBj1[ 'index'], genBj0['index'] # find Z in genLep (event.genLepZ_mass, genLepZ_l1_index, genLepZ_l2_index) = closestOSDLMassToMZ(promptGenLeps) genLepNonZ_indices = [ i for i in range(len(promptGenLeps)) if i not in [genLepZ_l1_index, genLepZ_l2_index] ] event.genLepZ_l1_index = promptGenLeps[genLepZ_l1_index][ 'index'] if genLepZ_l1_index >= 0 else -1 event.genLepZ_l2_index = promptGenLeps[genLepZ_l2_index][ 'index'] if genLepZ_l2_index >= 0 else -1 event.genLepNonZ_l1_index = promptGenLeps[genLepNonZ_indices[0]][ 'index'] if len(genLepNonZ_indices) > 0 else -1 event.genLepNonZ_l2_index = promptGenLeps[genLepNonZ_indices[1]][ 'index'] if len(genLepNonZ_indices) > 1 else -1 # store genLepZ stuff if event.genLepZ_mass > 0: genLepZ_l1 = ROOT.TLorentzVector() genLepZ_l1.SetPtEtaPhiM( promptGenLeps[event.genLepZ_l1_index]['pt'], promptGenLeps[event.genLepZ_l1_index]['eta'], promptGenLeps[event.genLepZ_l1_index]['phi'], 0) genLepZ_l2 = ROOT.TLorentzVector() genLepZ_l2.SetPtEtaPhiM( promptGenLeps[event.genLepZ_l2_index]['pt'], promptGenLeps[event.genLepZ_l2_index]['eta'], promptGenLeps[event.genLepZ_l2_index]['phi'], 0) genLepZ = genLepZ_l1 + genLepZ_l2 event.genLepZ_pt = genLepZ.Pt() event.genLepZ_eta = genLepZ.Eta() event.genLepZ_phi = genLepZ.Phi() event.genLepZ_lldPhi = deltaPhi( promptGenLeps[event.genLepZ_l1_index]['phi'], promptGenLeps[event.genLepZ_l2_index]['phi']) event.genLepZ_lldR = deltaR(promptGenLeps[event.genLepZ_l1_index], promptGenLeps[event.genLepZ_l2_index]) genLepMinus_index = event.genLepZ_l1_index if promptGenLeps[ event. genLepZ_l1_index]['pdgId'] > 0 else event.genLepZ_l2_index event.genLepZ_cosThetaStar = cosThetaStar( event.genLepZ_mass, event.genLepZ_pt, event.genLepZ_eta, event.genLepZ_phi, promptGenLeps[genLepMinus_index]['pt'], promptGenLeps[genLepMinus_index]['eta'], promptGenLeps[genLepMinus_index]['phi']) # reco-bjet/nonZ lepton association if event.genLepNonZ_l1_index >= 0 and genBj0 and genBj1: if vecSumPt(genBj0, promptGenLeps[event.genLepNonZ_l1_index], genMet) > vecSumPt( genBj1, promptGenLeps[event.genLepNonZ_l1_index], genMet): event.genBjNonZlep_index, event.genBjNonZhad_index = genBj0[ 'index'], genBj1['index'] else: event.genBjNonZlep_index, event.genBjNonZhad_index = genBj1[ 'index'], genBj0['index'] #for jet in genJets: # print jet['isMuon'], jet['isElectron'], jet['isPhoton'], min([999]+[deltaR2(jet, l) for l in promptGenLeps if l['pt']>10]), jet # jet/lepton disambiguation -> remove jets, because gen-jets cluster all leptons #if args.logLevel == 'DEBUG': # for jet in filter( lambda j: not (min([999]+[deltaR2(j, l) for l in promptGenLeps if l['pt']>10]) > 0.3**2 ), genJets ): # logger.debug( "Filtered gen %f jet %r lep %r", sqrt((min([999]+[deltaR2(jet, l) for l in promptGenLeps if l['pt']>10]))), jet, [ (l['eta'], jet['pt']/l['pt']) for l in promptGenLeps] ) # assert False, "" fill_vector_collection(event, "genPhoton", gen_photon_varnames, genPhotons_) fill_vector_collection(event, "genLep", lep_all_varnames, promptGenLeps) fill_vector_collection(event, "genJet", jet_write_varnames, genJets) # Reco quantities if args.delphes or args.HEPMC: #delphesReader.event.GetEntry(fwliteReader.position-1 ) # do this differently now ... # add JEC info allRecoJets = delphesReader.jets() # add btag info for i_btagWP, btagWP in enumerate(btagWPs): count = 0 for jet in allRecoJets: btag = (jet["bTag"] & (2**i_btagWP) > 0) # Read b-tag bitmap jet["bTag_" + btagWP] = btag # read jets recoJets = filter(isGoodRecoJet, allRecoJets) recoJets.sort(key=lambda p: -p['pt']) addIndex(recoJets) # count b-tag multiplicities for i_btagWP, btagWP in enumerate(btagWPs): count = 0 for jet in recoJets: if jet["bTag_" + btagWP]: count += 1 setattr(event, "nBTag_" + btagWP, count) if btagWP == default_btagWP: setattr(event, "nBTag", count) # upgrade JEC are flavor dependent for jet in allRecoJets: btag_ = jet["bTag_" + default_btagWP] upgradeJECUncertainty.applyJECInfo(jet, flavor=5 if btag else 0) # count JEC varied jet multiplicities event.nrecoJets_JEC_up = len( filter(lambda j: isGoodRecoJet(j, pt_var='pt_JEC_up'), allRecoJets)) event.nrecoJets_JEC_down = len( filter(lambda j: isGoodRecoJet(j, pt_var='pt_JEC_down'), allRecoJets)) event.nBTag_JEC_up = len( filter( lambda j: j["bTag_" + default_btagWP] and isGoodRecoJet( j, pt_var='pt_JEC_up'), allRecoJets)) event.nBTag_JEC_down = len( filter( lambda j: j["bTag_" + default_btagWP] and isGoodRecoJet( j, pt_var='pt_JEC_down'), allRecoJets)) # read jets recoJets = filter(isGoodRecoJet, allRecoJets) recoJets.sort(key=lambda p: -p['pt']) addIndex(recoJets) # make reco b jets recoBJets = filter(lambda j: j['bTag_' + default_btagWP], recoJets) recoNonBJets = filter(lambda j: not j['bTag_' + default_btagWP], recoJets) recoBj0, recoBj1 = (recoBJets + recoNonBJets + [None, None])[:2] if recoBj0: fill_vector(event, "recoBj0", recoJet_varnames, recoBj0) if recoBj1: fill_vector(event, "recoBj1", recoJet_varnames, recoBj1) # add b-tag reweights event.reweight_BTag_B = getBTagSF_1a(default_btagWP, 'B', recoBJets, recoNonBJets) event.reweight_BTag_L = getBTagSF_1a(default_btagWP, 'L', recoBJets, recoNonBJets) # read leptons allRecoLeps = delphesReader.muons() + delphesReader.electrons() allRecoLeps.sort(key=lambda p: -p['pt']) recoLeps = filter(isGoodRecoLepton, allRecoLeps) # Photons recoPhotons = filter(isGoodRecoPhoton, delphesReader.photons()) # Remove radiated photons in dR cone for recoPhoton in recoPhotons: recoPhoton['minLeptonDR'] = 999 recoPhoton['minLeptonPt'] = -1. dr_values = [deltaR(recoPhoton, l) for l in allRecoLeps] recoPhoton['minLeptonDR'] = min([999] + dr_values) if len(dr_values) > 0: closest_lepton = dr_values.index(min(dr_values)) recoPhoton['minLeptonPt'] = allRecoLeps[closest_lepton]['pt'] recoPhotons = list( filter(lambda g: g['minLeptonDR'] > 0.4, recoPhotons)) for recoPhoton in recoPhotons: recoPhoton['minJetDR'] = min( [999] + [deltaR(recoPhoton, j) for j in recoJets]) recoPhotons = list(filter(lambda g: g['minJetDR'] > 0.4, recoPhotons)) # cross-cleaning of reco-objects recoLeps = filter( lambda l: (min([999] + [deltaR2(l, j) for j in recoJets if j['pt'] > 30]) > 0.3**2), recoLeps) # give index to leptons addIndex(recoLeps) # lepton uncertainties event.reweight_id_mu = 1. event.reweight_id_ele = 1. for l in recoLeps: if abs(l['pdgId']) == 11: event.reweight_id_ele *= 1.005 elif abs(l['pdgId']) == 13: event.reweight_id_mu *= 1.005 # MET recoMet = delphesReader.met()[0] # reco-bjet/leading lepton association if len(recoLeps) > 0 and recoBj0 and recoBj1: if vecSumPt(recoBj0, recoLeps[0], recoMet) > vecSumPt( recoBj1, recoLeps[0], recoMet): event.recoBjLeadlep_index, event.recoBjLeadhad_index = recoBj0[ 'index'], recoBj1['index'] else: event.recoBjLeadlep_index, event.recoBjLeadhad_index = recoBj1[ 'index'], recoBj0['index'] # Photons for recoPhoton in recoPhotons: recoPhoton['genIndex'] = -1 minDR = 999 if not args.HEPMC: for index, genPhoton in enumerate(genPhotons_): dr = deltaR(recoPhoton, genPhoton) if dr < 0.4 and dr < minDR: minDR = dr recoPhoton['genIndex'] = index # Store fill_vector_collection(event, "recoLep", recoLep_varnames, recoLeps) fill_vector_collection(event, "recoJet", recoJet_varnames, recoJets) fill_vector_collection(event, "recoPhoton", recoPhoton_varnames, recoPhotons) event.recoMet_pt = recoMet['pt'] event.recoMet_phi = recoMet['phi'] # search for reco Z in reco leptons (event.recoZ_mass, recoZ_l1_index, recoZ_l2_index) = closestOSDLMassToMZ(recoLeps) recoNonZ_indices = [ i for i in range(len(recoLeps)) if i not in [recoZ_l1_index, recoZ_l2_index] ] event.recoZ_l1_index = recoLeps[recoZ_l1_index][ 'index'] if recoZ_l1_index >= 0 else -1 event.recoZ_l2_index = recoLeps[recoZ_l2_index][ 'index'] if recoZ_l2_index >= 0 else -1 event.recoNonZ_l1_index = recoLeps[ recoNonZ_indices[0]]['index'] if len(recoNonZ_indices) > 0 else -1 event.recoNonZ_l2_index = recoLeps[ recoNonZ_indices[1]]['index'] if len(recoNonZ_indices) > 1 else -1 # Store Z information if event.recoZ_mass >= 0: if recoLeps[event.recoZ_l1_index]['pdgId'] * recoLeps[ event.recoZ_l2_index]['pdgId'] > 0 or abs( recoLeps[event.recoZ_l1_index]['pdgId']) != abs( recoLeps[event.recoZ_l2_index]['pdgId']): raise RuntimeError("not a Z! Should not happen") Z_l1 = ROOT.TLorentzVector() Z_l1.SetPtEtaPhiM(recoLeps[event.recoZ_l1_index]['pt'], recoLeps[event.recoZ_l1_index]['eta'], recoLeps[event.recoZ_l1_index]['phi'], 0) Z_l2 = ROOT.TLorentzVector() Z_l2.SetPtEtaPhiM(recoLeps[event.recoZ_l2_index]['pt'], recoLeps[event.recoZ_l2_index]['eta'], recoLeps[event.recoZ_l2_index]['phi'], 0) Z = Z_l1 + Z_l2 event.recoZ_pt = Z.Pt() event.recoZ_eta = Z.Eta() event.recoZ_phi = Z.Phi() event.recoZ_lldPhi = deltaPhi( recoLeps[event.recoZ_l1_index]['phi'], recoLeps[event.recoZ_l2_index]['phi']) event.recoZ_lldR = deltaR(recoLeps[event.recoZ_l1_index], recoLeps[event.recoZ_l2_index]) lm_index = event.recoZ_l1_index if recoLeps[ event.recoZ_l1_index]['pdgId'] > 0 else event.recoZ_l2_index event.recoZ_cosThetaStar = cosThetaStar( event.recoZ_mass, event.recoZ_pt, event.recoZ_eta, event.recoZ_phi, recoLeps[lm_index]['pt'], recoLeps[lm_index]['eta'], recoLeps[lm_index]['phi']) # reco-bjet/lepton association if event.recoNonZ_l1_index >= 0 and recoBj0 and recoBj1: if vecSumPt(recoBj0, recoLeps[event.recoNonZ_l1_index], recoMet) > vecSumPt( recoBj1, recoLeps[event.recoNonZ_l1_index], recoMet): event.recoBjNonZlep_index, event.recoBjNonZhad_index = recoBj0[ 'index'], recoBj1['index'] else: event.recoBjNonZlep_index, event.recoBjNonZhad_index = recoBj1[ 'index'], recoBj0['index']