def SS_selection(lep1, lep2): selection = PackedSelection() is_dilep = ((ak.num(lep1) + ak.num(lep2))==2) pos_charge = ((ak.sum(lep1.pdgId, axis=1) + ak.sum(lep2.pdgId, axis=1))<0) neg_charge = ((ak.sum(lep1.pdgId, axis=1) + ak.sum(lep2.pdgId, axis=1))>0) dilep2 = choose(lep2, 2) dilep1 = choose(lep1, 2) dilep = cross(lep2, lep1) is_SS = ( ak.any((dilep2['0'].charge * dilep2['1'].charge)>0, axis=1) | \ ak.any((dilep1['0'].charge * dilep1['1'].charge)>0, axis=1) | \ ak.any((dilep['0'].charge * dilep['1'].charge)>0, axis=1) ) selection.add('SS', is_SS) ss_reqs = ['SS'] ss_reqs_d = {sel: True for sel in ss_reqs} ss_selection = selection.require(**ss_reqs_d) return ss_selection
def dilep_baseline(self, omit=[], cutflow=None, tight=False, SS=True): ''' give it a cutflow object if you want it to be filed. cuts in the omit list will not be applied ''' self.selection = PackedSelection() is_dilep = ((ak.num(self.ele) + ak.num(self.mu))==2) pos_charge = ((ak.sum(self.ele.pdgId, axis=1) + ak.sum(self.mu.pdgId, axis=1))<0) neg_charge = ((ak.sum(self.ele.pdgId, axis=1) + ak.sum(self.mu.pdgId, axis=1))>0) lep0pt = ((ak.num(self.ele[(self.ele.pt>25)]) + ak.num(self.mu[(self.mu.pt>25)]))>0) lep1pt = ((ak.num(self.ele[(self.ele.pt>20)]) + ak.num(self.mu[(self.mu.pt>20)]))>1) lepveto = ((ak.num(self.ele_veto) + ak.num(self.mu_veto))==2) dimu = choose(self.mu, 2) diele = choose(self.ele, 2) dilep = cross(self.mu, self.ele) if SS: is_SS = ( ak.any((dimu['0'].charge * dimu['1'].charge)>0, axis=1) | \ ak.any((diele['0'].charge * diele['1'].charge)>0, axis=1) | \ ak.any((dilep['0'].charge * dilep['1'].charge)>0, axis=1) ) else: is_OS = ( ak.any((dimu['0'].charge * dimu['1'].charge)<0, axis=1) | \ ak.any((diele['0'].charge * diele['1'].charge)<0, axis=1) | \ ak.any((dilep['0'].charge * dilep['1'].charge)<0, axis=1) ) lepton = ak.concatenate([self.ele, self.mu], axis=1) lepton_pdgId_pt_ordered = ak.fill_none( ak.pad_none( lepton[ak.argsort(lepton.pt, ascending=False)].pdgId, 2, clip=True), 0) triggers = getTriggers(self.events, ak.flatten(lepton_pdgId_pt_ordered[:,0:1]), ak.flatten(lepton_pdgId_pt_ordered[:,1:2]), year=self.year, dataset=self.dataset) ht = ak.sum(self.jet_all.pt, axis=1) st = self.met.pt + ht + ak.sum(self.mu.pt, axis=1) + ak.sum(self.ele.pt, axis=1) self.selection.add('lepveto', lepveto) self.selection.add('dilep', is_dilep) #self.selection.add('filter', self.filters) self.selection.add('trigger', triggers) self.selection.add('p_T(lep0)>25', lep0pt) self.selection.add('p_T(lep1)>20', lep1pt) if SS: self.selection.add('SS', is_SS ) else: self.selection.add('OS', is_OS ) self.selection.add('N_jet>3', (ak.num(self.jet_all)>3) ) self.selection.add('N_jet>4', (ak.num(self.jet_all)>4) ) self.selection.add('N_central>2', (ak.num(self.jet_central)>2) ) self.selection.add('N_central>3', (ak.num(self.jet_central)>3) ) self.selection.add('N_btag>0', (ak.num(self.jet_btag)>0) ) self.selection.add('N_fwd>0', (ak.num(self.jet_fwd)>0) ) self.selection.add('MET>30', (self.met.pt>30) ) self.selection.add('MET>50', (self.met.pt>50) ) self.selection.add('ST>600', (st>600) ) ss_reqs = [ # 'filter', 'lepveto', 'dilep', 'p_T(lep0)>25', 'p_T(lep1)>20', 'trigger', 'SS' if SS else 'OS', 'N_jet>3', 'N_central>2', 'N_btag>0', 'MET>30', 'N_fwd>0', ] if tight: ss_reqs += [ 'N_jet>4', 'N_central>3', 'ST>600', 'MET>50', #'delta_eta', ] ss_reqs_d = { sel: True for sel in ss_reqs if not sel in omit } ss_selection = self.selection.require(**ss_reqs_d) if cutflow: # cutflow_reqs_d = {} for req in ss_reqs: cutflow_reqs_d.update({req: True}) cutflow.addRow( req, self.selection.require(**cutflow_reqs_d) ) return ss_selection
def trilep_baseline(self, omit=[], cutflow=None, tight=False): ''' give it a cutflow object if you want it to be filed. cuts in the omit list will not be applied ''' self.selection = PackedSelection() is_trilep = ((ak.num(self.ele) + ak.num(self.mu))==3) los_trilep = ((ak.num(self.ele) + ak.num(self.mu))>=2) pos_charge = ((ak.sum(self.ele.pdgId, axis=1) + ak.sum(self.mu.pdgId, axis=1))<0) neg_charge = ((ak.sum(self.ele.pdgId, axis=1) + ak.sum(self.mu.pdgId, axis=1))>0) lep0pt = ((ak.num(self.ele[(self.ele.pt>25)]) + ak.num(self.mu[(self.mu.pt>25)]))>0) lep1pt = ((ak.num(self.ele[(self.ele.pt>20)]) + ak.num(self.mu[(self.mu.pt>20)]))>1) lepveto = ((ak.num(self.ele_veto) + ak.num(self.mu_veto))==3) dimu = choose(self.mu, 2) diele = choose(self.ele, 2) dimu_veto = choose(self.mu_veto,2) diele_veto = choose(self.ele_veto,2) #dilep = cross(self.mu, self.ele) OS_dimu = dimu[(dimu['0'].charge*dimu['1'].charge < 0)] OS_diele = diele[(diele['0'].charge*diele['1'].charge < 0)] OS_dimu_veto = dimu_veto[(dimu_veto['0'].charge*dimu_veto['1'].charge < 0)] OS_diele_veto = diele_veto[(diele_veto['0'].charge*diele_veto['1'].charge < 0)] SFOS = ak.concatenate([OS_diele_veto, OS_dimu_veto], axis=1) offZ = (ak.all(abs(OS_dimu.mass-91.2)>10, axis=1) & ak.all(abs(OS_diele.mass-91.2)>10, axis=1)) offZ_veto = (ak.all(abs(OS_dimu_veto.mass-91.2)>10, axis=1) & ak.all(abs(OS_diele_veto.mass-91.2)>10, axis=1)) lepton = ak.concatenate([self.ele, self.mu], axis=1) lepton_pdgId_pt_ordered = ak.fill_none(ak.pad_none(lepton[ak.argsort(lepton.pt, ascending=False)].pdgId, 2, clip=True), 0) dilep = choose(lepton,2) SS_dilep = (dilep['0'].charge*dilep['1'].charge > 0) los_trilep_SS = (ak.any(SS_dilep, axis=1)) vetolepton = ak.concatenate([self.ele_veto, self.mu_veto], axis=1) vetotrilep = choose3(vetolepton, 3) pos_trilep = ak.any((vetotrilep['0'].charge+vetotrilep['1'].charge+vetotrilep['2'].charge > 0),axis=1) neg_trilep = ak.any((vetotrilep['0'].charge+vetotrilep['1'].charge+vetotrilep['2'].charge < 0),axis=1) triggers = getTriggers(self.events, ak.flatten(lepton_pdgId_pt_ordered[:,0:1]), ak.flatten(lepton_pdgId_pt_ordered[:,1:2]), year=self.year, dataset=self.dataset) ht = ak.sum(self.jet_all.pt, axis=1) st = self.met.pt + ht + ak.sum(self.mu.pt, axis=1) + ak.sum(self.ele.pt, axis=1) st_veto = self.met.pt + ht + ak.sum(self.mu_veto.pt, axis=1) + ak.sum(self.ele_veto.pt, axis=1) lep0pt_veto = ((ak.num(self.ele_veto[(self.ele_veto.pt>25)]) + ak.num(self.mu_veto[(self.mu_veto.pt>25)]))>0) lep1pt_veto = ((ak.num(self.ele_veto[(self.ele_veto.pt>20)]) + ak.num(self.mu_veto[(self.mu_veto.pt>20)]))>1) self.selection.add('lepveto', lepveto) self.selection.add('trilep', los_trilep_SS) self.selection.add('filter', self.filters) self.selection.add('trigger', triggers) self.selection.add('p_T(lep0)>25', lep0pt_veto) self.selection.add('p_T(lep1)>20', lep1pt_veto) self.selection.add('N_jet>2', (ak.num(self.jet_all)>2) ) self.selection.add('N_jet>3', (ak.num(self.jet_all)>3) ) self.selection.add('N_central>1', (ak.num(self.jet_central)>1) ) self.selection.add('N_central>2', (ak.num(self.jet_central)>2) ) self.selection.add('N_btag>0', (ak.num(self.jet_btag)>0 )) self.selection.add('N_fwd>0', (ak.num(self.jet_fwd)>0) ) self.selection.add('MET>50', (self.met.pt>50) ) self.selection.add('ST>600', (st_veto>600) ) self.selection.add('offZ', offZ_veto ) #self.selection.add('SFOS>=1', ak.num(SFOS)==0) #self.selection.add('charge_sum', neg_trilep) reqs = [ 'filter', 'lepveto', 'trilep', 'p_T(lep0)>25', 'p_T(lep1)>20', 'trigger', 'offZ', 'MET>50', 'N_jet>2', 'N_central>1', 'N_btag>0', 'N_fwd>0', #'SFOS>=1', #'charge_sum' ] if tight: reqs += [ 'N_jet>3', 'N_central>2', 'ST>600', #'MET>50', #'delta_eta', ] reqs_d = { sel: True for sel in reqs if not sel in omit } selection = self.selection.require(**reqs_d) self.reqs = [ sel for sel in reqs if not sel in omit ] if cutflow: # cutflow_reqs_d = {} for req in reqs: cutflow_reqs_d.update({req: True}) cutflow.addRow( req, self.selection.require(**cutflow_reqs_d) ) return selection
def process(self, events): output = self.accumulator.identity() # we can use a very loose preselection to filter the events. nothing is done with this presel, though presel = ak.num(events.Jet) > 0 if self.year == 2016: lumimask = LumiMask( '../data/lumi/Cert_271036-284044_13TeV_Legacy2016_Collisions16_JSON.txt' ) if self.year == 2017: lumimask = LumiMask( '../data/lumi/Cert_294927-306462_13TeV_UL2017_Collisions17_GoldenJSON.txt' ) if self.year == 2018: lumimask = LumiMask( '../data/lumi/Cert_314472-325175_13TeV_Legacy2018_Collisions18_JSON.txt' ) ev = events[presel] dataset = ev.metadata['dataset'] # load the config - probably not needed anymore cfg = loadConfig() output['totalEvents']['all'] += len(events) output['skimmedEvents']['all'] += len(ev) if self.year == 2018: triggers = ev.HLT.Ele23_Ele12_CaloIdL_TrackIdL_IsoVL elif self.year == 2017: triggers = ev.HLT.Ele23_Ele12_CaloIdL_TrackIdL_IsoVL elif self.year == 2016: triggers = ev.HLT.Ele23_Ele12_CaloIdL_TrackIdL_IsoVL_DZ ## Electrons electron = Collections(ev, "Electron", "tightFCNC", 0, self.year).get() electron = electron[(electron.pt > 25) & (np.abs(electron.eta) < 2.4)] loose_electron = Collections(ev, "Electron", "looseFCNC", 0, self.year).get() loose_electron = loose_electron[(loose_electron.pt > 25) & (np.abs(loose_electron.eta) < 2.4)] SSelectron = (ak.sum(electron.charge, axis=1) != 0) & (ak.num(electron) == 2) OSelectron = (ak.sum(electron.charge, axis=1) == 0) & (ak.num(electron) == 2) dielectron = choose(electron, 2) dielectron_mass = (dielectron['0'] + dielectron['1']).mass dielectron_pt = (dielectron['0'] + dielectron['1']).pt leading_electron_idx = ak.singletons(ak.argmax(electron.pt, axis=1)) leading_electron = electron[(leading_electron_idx)] leading_electron = leading_electron[(leading_electron.pt > 30)] trailing_electron_idx = ak.singletons(ak.argmin(electron.pt, axis=1)) trailing_electron = electron[trailing_electron_idx] ##Muons loose_muon = Collections(ev, "Muon", "looseFCNC", 0, self.year).get() loose_muon = loose_muon[(loose_muon.pt > 20) & (np.abs(loose_muon.eta) < 2.4)] #jets jet = getJets(ev, minPt=40, maxEta=2.4, pt_var='pt') jet = jet[~match(jet, loose_muon, deltaRCut=0.4)] # remove jets that overlap with muons jet = jet[~match( jet, electron, deltaRCut=0.4)] # remove jets that overlap with electrons ## MET -> can switch to puppi MET met_pt = ev.MET.pt met_phi = ev.MET.phi #weights weight = Weights(len(ev)) weight2 = Weights(len(ev)) weight2.add("charge flip", self.charge_flip_ratio.flip_weight(electron)) #selections filters = getFilters(ev, year=self.year, dataset=dataset, UL=False) mask = lumimask(ev.run, ev.luminosityBlock) ss = (SSelectron) os = (OSelectron) mass = (ak.min(np.abs(dielectron_mass - 91.2), axis=1) < 15) lead_electron = (ak.min(leading_electron.pt, axis=1) > 30) jet1 = (ak.num(jet) >= 1) jet2 = (ak.num(jet) >= 2) num_loose = ((ak.num(loose_electron) == 2) & (ak.num(loose_muon) == 0)) selection = PackedSelection() selection.add('filter', (filters)) selection.add('mask', (mask)) selection.add('ss', ss) selection.add('os', os) selection.add('mass', mass) selection.add('leading', lead_electron) selection.add('triggers', triggers) selection.add('one jet', jet1) selection.add('two jets', jet2) selection.add('num_loose', num_loose) bl_reqs = ['filter'] + ['triggers'] + ['mask'] bl_reqs_d = {sel: True for sel in bl_reqs} baseline = selection.require(**bl_reqs_d) s_reqs = bl_reqs + ['ss'] + ['mass'] + ['num_loose'] + ['leading'] s_reqs_d = {sel: True for sel in s_reqs} ss_sel = selection.require(**s_reqs_d) o_reqs = bl_reqs + ['os'] + ['mass'] + ['num_loose'] + ['leading'] o_reqs_d = {sel: True for sel in o_reqs} os_sel = selection.require(**o_reqs_d) j1s_reqs = s_reqs + ['one jet'] j1s_reqs_d = {sel: True for sel in j1s_reqs} j1ss_sel = selection.require(**j1s_reqs_d) j1o_reqs = o_reqs + ['one jet'] j1o_reqs_d = {sel: True for sel in j1o_reqs} j1os_sel = selection.require(**j1o_reqs_d) j2s_reqs = s_reqs + ['two jets'] j2s_reqs_d = {sel: True for sel in j2s_reqs} j2ss_sel = selection.require(**j2s_reqs_d) j2o_reqs = o_reqs + ['two jets'] j2o_reqs_d = {sel: True for sel in j2o_reqs} j2os_sel = selection.require(**j2o_reqs_d) #outputs output["electron_data1"].fill( dataset=dataset, pt=ak.to_numpy(ak.flatten(leading_electron[os_sel].pt)), eta=ak.to_numpy(ak.flatten(leading_electron[os_sel].eta)), phi=ak.to_numpy(ak.flatten(leading_electron[os_sel].phi)), weight=weight2.weight()[os_sel]) output["electron_data2"].fill( dataset=dataset, pt=ak.to_numpy(ak.flatten(trailing_electron[os_sel].pt)), eta=ak.to_numpy(ak.flatten(trailing_electron[os_sel].eta)), phi=ak.to_numpy(ak.flatten(trailing_electron[os_sel].phi)), weight=weight2.weight()[os_sel]) output["electron_data3"].fill( dataset=dataset, pt=ak.to_numpy(ak.flatten(leading_electron[j1os_sel].pt)), eta=ak.to_numpy(ak.flatten(leading_electron[j1os_sel].eta)), phi=ak.to_numpy(ak.flatten(leading_electron[j1os_sel].phi)), weight=weight2.weight()[j1os_sel]) output["electron_data4"].fill( dataset=dataset, pt=ak.to_numpy(ak.flatten(trailing_electron[j1os_sel].pt)), eta=ak.to_numpy(ak.flatten(trailing_electron[j1os_sel].eta)), phi=ak.to_numpy(ak.flatten(trailing_electron[j1os_sel].phi)), weight=weight2.weight()[j1os_sel]) output["electron_data5"].fill( dataset=dataset, pt=ak.to_numpy(ak.flatten(leading_electron[j2os_sel].pt)), eta=ak.to_numpy(ak.flatten(leading_electron[j2os_sel].eta)), phi=ak.to_numpy(ak.flatten(leading_electron[j2os_sel].phi)), weight=weight2.weight()[j2os_sel]) output["electron_data6"].fill( dataset=dataset, pt=ak.to_numpy(ak.flatten(trailing_electron[j2os_sel].pt)), eta=ak.to_numpy(ak.flatten(trailing_electron[j2os_sel].eta)), phi=ak.to_numpy(ak.flatten(trailing_electron[j2os_sel].phi)), weight=weight2.weight()[j2os_sel]) output["electron_data7"].fill( dataset=dataset, pt=ak.to_numpy(ak.flatten(leading_electron[ss_sel].pt)), eta=ak.to_numpy(ak.flatten(leading_electron[ss_sel].eta)), phi=ak.to_numpy(ak.flatten(leading_electron[ss_sel].phi)), weight=weight.weight()[ss_sel]) output["electron_data8"].fill( dataset=dataset, pt=ak.to_numpy(ak.flatten(trailing_electron[ss_sel].pt)), eta=ak.to_numpy(ak.flatten(trailing_electron[ss_sel].eta)), phi=ak.to_numpy(ak.flatten(trailing_electron[ss_sel].phi)), weight=weight.weight()[ss_sel]) output["electron_data9"].fill( dataset=dataset, pt=ak.to_numpy(ak.flatten(leading_electron[j1ss_sel].pt)), eta=ak.to_numpy(ak.flatten(leading_electron[j1ss_sel].eta)), phi=ak.to_numpy(ak.flatten(leading_electron[j1ss_sel].phi)), weight=weight.weight()[j1ss_sel]) output["electron_data10"].fill( dataset=dataset, pt=ak.to_numpy(ak.flatten(trailing_electron[j1ss_sel].pt)), eta=ak.to_numpy(ak.flatten(trailing_electron[j1ss_sel].eta)), phi=ak.to_numpy(ak.flatten(trailing_electron[j1ss_sel].phi)), weight=weight.weight()[j1ss_sel]) output["electron_data11"].fill( dataset=dataset, pt=ak.to_numpy(ak.flatten(leading_electron[j2ss_sel].pt)), eta=ak.to_numpy(ak.flatten(leading_electron[j2ss_sel].eta)), phi=ak.to_numpy(ak.flatten(leading_electron[j2ss_sel].phi)), weight=weight.weight()[j2ss_sel]) output["electron_data12"].fill( dataset=dataset, pt=ak.to_numpy(ak.flatten(trailing_electron[j2ss_sel].pt)), eta=ak.to_numpy(ak.flatten(trailing_electron[j2ss_sel].eta)), phi=ak.to_numpy(ak.flatten(trailing_electron[j2ss_sel].phi)), weight=weight.weight()[j2ss_sel]) output["dilep_mass1"].fill( dataset=dataset, mass=ak.to_numpy(ak.flatten(dielectron_mass[os_sel])), pt=ak.to_numpy(ak.flatten(dielectron_pt[os_sel])), weight=weight2.weight()[os_sel]) output["dilep_mass2"].fill( dataset=dataset, mass=ak.to_numpy(ak.flatten(dielectron_mass[j1os_sel])), pt=ak.to_numpy(ak.flatten(dielectron_pt[j1os_sel])), weight=weight2.weight()[j1os_sel]) output["dilep_mass3"].fill( dataset=dataset, mass=ak.to_numpy(ak.flatten(dielectron_mass[j2os_sel])), pt=ak.to_numpy(ak.flatten(dielectron_pt[j2os_sel])), weight=weight2.weight()[j2os_sel]) output["dilep_mass4"].fill( dataset=dataset, mass=ak.to_numpy(ak.flatten(dielectron_mass[ss_sel])), pt=ak.to_numpy(ak.flatten(dielectron_pt[ss_sel])), weight=weight.weight()[ss_sel]) output["dilep_mass5"].fill( dataset=dataset, mass=ak.to_numpy(ak.flatten(dielectron_mass[j1ss_sel])), pt=ak.to_numpy(ak.flatten(dielectron_pt[j1ss_sel])), weight=weight.weight()[j1ss_sel]) output["dilep_mass6"].fill( dataset=dataset, mass=ak.to_numpy(ak.flatten(dielectron_mass[j2ss_sel])), pt=ak.to_numpy(ak.flatten(dielectron_pt[j2ss_sel])), weight=weight.weight()[j2ss_sel]) output["MET"].fill(dataset=dataset, pt=met_pt[os_sel], weight=weight2.weight()[os_sel]) output["MET2"].fill(dataset=dataset, pt=met_pt[j1os_sel], weight=weight2.weight()[j1os_sel]) output["MET3"].fill(dataset=dataset, pt=met_pt[j2os_sel], weight=weight2.weight()[j2os_sel]) output["MET4"].fill(dataset=dataset, pt=met_pt[ss_sel], weight=weight.weight()[ss_sel]) output["MET5"].fill(dataset=dataset, pt=met_pt[j1ss_sel], weight=weight.weight()[j1ss_sel]) output["MET6"].fill(dataset=dataset, pt=met_pt[j2ss_sel], weight=weight.weight()[j2ss_sel]) output["N_jet"].fill(dataset=dataset, multiplicity=ak.num(jet)[os_sel], weight=weight2.weight()[os_sel]) output["N_jet2"].fill(dataset=dataset, multiplicity=ak.num(jet)[j1os_sel], weight=weight2.weight()[j1os_sel]) output["N_jet3"].fill(dataset=dataset, multiplicity=ak.num(jet)[j2os_sel], weight=weight2.weight()[j2os_sel]) output["N_jet4"].fill(dataset=dataset, multiplicity=ak.num(jet)[ss_sel], weight=weight.weight()[ss_sel]) output["N_jet5"].fill(dataset=dataset, multiplicity=ak.num(jet)[j1ss_sel], weight=weight.weight()[j1ss_sel]) output["N_jet6"].fill(dataset=dataset, multiplicity=ak.num(jet)[j2ss_sel], weight=weight.weight()[j2ss_sel]) output["PV_npvsGood"].fill(dataset=dataset, multiplicity=ev.PV[os_sel].npvsGood, weight=weight2.weight()[os_sel]) output["PV_npvsGood2"].fill(dataset=dataset, multiplicity=ev.PV[j1os_sel].npvsGood, weight=weight2.weight()[j1os_sel]) output["PV_npvsGood3"].fill(dataset=dataset, multiplicity=ev.PV[j2os_sel].npvsGood, weight=weight2.weight()[j2os_sel]) output["PV_npvsGood4"].fill(dataset=dataset, multiplicity=ev.PV[ss_sel].npvsGood, weight=weight.weight()[ss_sel]) output["PV_npvsGood5"].fill(dataset=dataset, multiplicity=ev.PV[j1ss_sel].npvsGood, weight=weight.weight()[j1ss_sel]) output["PV_npvsGood6"].fill(dataset=dataset, multiplicity=ev.PV[j2ss_sel].npvsGood, weight=weight.weight()[j2ss_sel]) return output