def __init__(self, output, ev, weight, selection=None): ''' output: the accumulator object ev: NanoEvent weight: coffea analysis_tools Weights object ''' self.ev = ev self.weight = weight.weight() self.output = output self.selection = None self.addRow('entry', (ak.ones_like(self.weight) == 1))
def mask_or(ev, collection, masks): """Returns the OR of the masks in the list :param ev: NanoEvents :type ev: NanoEvents :param collection: HLT or Filter "type collection: string :param masks: Mask names as saved in the df :type masks: List :return: OR of all masks for each event :rtype: array """ # Start with array of False decision = (ak.ones_like(ev.MET.pt) == 0) coll = getattr(ev, collection) # Flip to true if any is passed for t in masks: try: decision = decision | getattr(coll, t) except KeyError: continue return decision
def build_weight_like(weight, selection, like): return ak.flatten(weight[selection] * ak.ones_like(like[selection]))
def __init__(self, ev, obj, wp, year=2018, verbose=0): self.obj = obj self.wp = wp if self.wp == None: self.selection_dict = {} else: self.selection_dict = obj_def[self.obj][self.wp] self.v = verbose self.year = year id_level = None if wp.lower().count('veto'): id_level = 0 elif wp.lower().count('fake'): id_level = 1 elif wp.lower().count('tight'): id_level = 2 if self.obj == "Muon": # collections are already there, so we just need to calculate missing ones ev['Muon', 'absMiniIso'] = ev.Muon.miniPFRelIso_all * ev.Muon.pt ev['Muon', 'ptErrRel'] = ev.Muon.ptErr / ev.Muon.pt # this is what we are using: # - jetRelIso if the matched jet is within deltaR<0.4, pfRelIso03_all otherwise # - btagDeepFlavB discriminator of the matched jet if jet is within deltaR<0.4, 0 otherwise # - pt_cone = 0.9*pt of matched jet if jet is within deltaR<0.4, pt/(pt+iso) otherwise mask_close = (ak.fill_none(ev.Muon.delta_r(ev.Muon.matched_jet), 99) < 0.4) * 1 mask_far = ~(ak.fill_none(ev.Muon.delta_r(ev.Muon.matched_jet), 99) < 0.4) * 1 deepJet = ak.fill_none(ev.Muon.matched_jet.btagDeepFlavB, 0) * mask_close + 0 * mask_far jetRelIsoV2 = ev.Muon.jetRelIso * mask_close + ev.Muon.pfRelIso03_all * mask_far # default to 0 if no match conePt = 0.9 * ak.fill_none( ev.Muon.matched_jet.pt, 0) * mask_close + (ev.Muon.pt * (1 + ev.Muon.miniPFRelIso_all)) * mask_far #conePt = 0.8 * ak.fill_none(ev.Muon.matched_jet.pt,0) * mask_close + (ev.Muon.pt/(1 + ev.Muon.miniPFRelIso_all))*mask_far ev['Muon', 'deepJet'] = ak.copy(deepJet) ev['Muon', 'jetRelIsoV2'] = jetRelIsoV2 ev['Muon', 'conePt'] = conePt ev['Muon', 'id'] = ak.ones_like(conePt) * id_level self.cand = ev.Muon elif self.obj == "Electron": # calculate new variables. asignment is awkward, but what can you do. ev['Electron', 'absMiniIso'] = ev.Electron.miniPFRelIso_all * ev.Electron.pt ev['Electron', 'etaSC'] = ev.Electron.eta + ev.Electron.deltaEtaSC # the following line is only needed if we do our own matching. # right now, we keep using the NanoAOD match, but check the deltaR distance # jet_index, mask_match, mask_nomatch = self.matchJets(ev.Electron, ev.Jet) # this is what we are using: # - jetRelIso if the matched jet is within deltaR<0.4, pfRelIso03_all otherwise # - btagDeepFlavB discriminator of the matched jet if jet is within deltaR<0.4, 0 otherwise # - pt_cone = 0.9*pt of matched jet if jet is within deltaR<0.4, pt/(pt+iso) otherwise mask_close = (ak.fill_none( ev.Electron.delta_r(ev.Electron.matched_jet), 99) < 0.4) * 1 mask_far = ~(ak.fill_none( ev.Electron.delta_r(ev.Electron.matched_jet), 99) < 0.4) * 1 deepJet = ak.fill_none(ev.Electron.matched_jet.btagDeepFlavB, 0) * mask_close jetRelIsoV2 = ev.Electron.jetRelIso * mask_close + ev.Electron.pfRelIso03_all * mask_far # default to 0 if no match conePt = 0.9 * ak.fill_none( ev.Electron.matched_jet.pt, 0) * mask_close + ( ev.Electron.pt * (1 + ev.Electron.miniPFRelIso_all)) * mask_far #conePt = 0.8 * ak.fill_none(ev.Electron.matched_jet.pt,0) * mask_close + (ev.Electron.pt/(1 + ev.Electron.miniPFRelIso_all))*mask_far ev['Electron', 'deepJet'] = ak.copy(deepJet) ev['Electron', 'jetRelIsoV2'] = jetRelIsoV2 ev['Electron', 'conePt'] = conePt ev['Electron', 'id'] = ak.ones_like(conePt) * id_level self.cand = ev.Electron self.getSelection() if self.obj == "Electron" and self.wp == "tight": self.selection = self.selection & self.getElectronMVAID( ) & self.getIsolation(0.07, 0.78, 8.0) & self.isTriggerSafeNoIso() if self.v > 0: print(" - custom ID and multi-isolation") if self.obj == "Muon" and self.wp == "tight": self.selection = self.selection & self.getIsolation( 0.11, 0.74, 6.8) if self.v > 0: print(" - custom multi-isolation") #self.selection = self.selection & ak.fill_none(ev.Muon.matched_jet.btagDeepFlavB<0.2770, True) #self.selection = self.selection & (ev.Muon.matched_jet.btagDeepFlavB<0.2770) #if self.v>0: print (" - deepJet") if self.obj == "Electron" and (self.wp == "tightTTH" or self.wp == 'fakeableTTH' or self.wp == "tightSSTTH" or self.wp == 'fakeableSSTTH'): self.selection = self.selection & self.getSigmaIEtaIEta() if self.v > 0: print(" - SigmaIEtaIEta") #self.selection = self.selection & ak.fill_none(ev.Electron.matched_jet.btagDeepFlavB<0.2770, True) #self.selection = self.selection & (ev.Electron.matched_jet.btagDeepFlavB<0.2770) #self.selection = self.selection & (ev.Jet[ev.Electron.jetIdx].btagDeepFlavB<0.2770) #if self.v>0: print (" - deepJet") if self.obj == 'Muon' and (self.wp == 'fakeableTTH' or self.wp == 'fakeableSSTTH'): #self.selection = self.selection & (self.cand.deepJet < self.getThreshold(self.cand.conePt, min_pt=20, max_pt=45, low=0.2770, high=0.0494)) self.selection = self.selection & (ak.fill_none( ev.Muon.matched_jet.btagDeepFlavB, 0) < self.getThreshold( self.cand.conePt, min_pt=20, max_pt=45)) if self.v > 0: print(" - interpolated deepJet")
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 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) ## Muons muon = ev.Muon ## Electrons electron = Collections(ev, "Electron", "tight").get() #electron = electron[(ak.nan_to_num(electron.eta, 99))] electron = electron[(electron.miniPFRelIso_all < 0.12) & (electron.pt > 20) & (abs(electron.eta) < 2.4)] gen_matched_electron = electron[((electron.genPartIdx >= 0) & (abs( electron.matched_gen.pdgId) == 11))] is_flipped = ((gen_matched_electron.matched_gen.pdgId * (-1) == gen_matched_electron.pdgId) & (abs(gen_matched_electron.pdgId) == 11)) #(abs(ev.GenPart[gen_matched_electron.genPartIdx].pdgId) ==abs(gen_matched_electron.pdgId))&(ev.GenPart[gen_matched_electron.genPartIdx].pdgId/abs(ev.GenPart[gen_matched_electron.genPartIdx].pdgId) != gen_matched_electron.pdgId/abs(gen_matched_electron.pdgId)) flipped_electron = gen_matched_electron[is_flipped] flipped_electron = flipped_electron[(ak.fill_none( flipped_electron.pt, 0) > 0)] n_flips = ak.num(flipped_electron) dielectron = choose(electron, 2) SSelectron = ak.any( (dielectron['0'].charge * dielectron['1'].charge) > 0, axis=1) leading_electron_idx = ak.singletons(ak.argmax(electron.pt, axis=1)) leading_electron = electron[leading_electron_idx] leading_flipped_electron_idx = ak.singletons( ak.argmax(flipped_electron.pt, axis=1)) leading_flipped_electron = electron[leading_flipped_electron_idx] ## MET -> can switch to puppi MET met_pt = ev.MET.pt met_phi = ev.MET.phi # setting up the various weights weight = Weights(len(ev)) if not dataset == 'MuonEG': # generator weight weight.add("weight", ev.genWeight) #selections filters = getFilters(ev, year=self.year, dataset=dataset) electr = ((ak.num(electron) >= 1)) gen_electr = ((ak.num(gen_matched_electron) >= 1)) ss = (SSelectron) flip = (n_flips >= 1) selection = PackedSelection() selection.add('filter', (filters)) selection.add('electr', electr) selection.add('ss', ss) selection.add('flip', flip) selection.add('gen_electr', gen_electr) bl_reqs = ['filter', 'electr', 'gen_electr'] bl_reqs_d = {sel: True for sel in bl_reqs} baseline = selection.require(**bl_reqs_d) f_reqs = bl_reqs + ['flip'] f_reqs_d = {sel: True for sel in f_reqs} flip_sel = selection.require(**f_reqs_d) #adjust weights to prevent length mismatch ak_weight_gen = ak.ones_like( gen_matched_electron[baseline].pt) * weight.weight()[baseline] ak_weight_flip = ak.ones_like( flipped_electron[flip_sel].pt) * weight.weight()[flip_sel] output['N_ele'].fill(dataset=dataset, multiplicity=ak.num(electron)[baseline], weight=weight.weight()[baseline]) output['electron_flips'].fill(dataset=dataset, multiplicity=n_flips[baseline], weight=weight.weight()[baseline]) output["electron"].fill( dataset=dataset, pt=ak.to_numpy(ak.flatten(gen_matched_electron[baseline].pt)), eta=abs(ak.to_numpy(ak.flatten( gen_matched_electron[baseline].eta))), #phi = ak.to_numpy(ak.flatten(leading_electron[baseline].phi)), #weight = ak.to_numpy(ak.flatten(ak_weight_gen)) ) output["electron2"].fill( dataset=dataset, pt=ak.to_numpy(ak.flatten(gen_matched_electron[baseline].pt)), eta=ak.to_numpy(ak.flatten(gen_matched_electron[baseline].eta)), #phi = ak.to_numpy(ak.flatten(leading_electron[baseline].phi)), #weight = ak.to_numpy(ak.flatten(ak_weight_gen)) ) output["flipped_electron"].fill( dataset=dataset, pt=ak.to_numpy(ak.flatten(flipped_electron[flip_sel].pt)), eta=abs(ak.to_numpy(ak.flatten(flipped_electron[flip_sel].eta))), #phi = ak.to_numpy(ak.flatten(flipped_electron[flip_sel].phi)), #weight = ak.to_numpy(ak.flatten(ak_weight_flip)) ) output["flipped_electron2"].fill( dataset=dataset, pt=ak.to_numpy(ak.flatten(flipped_electron[flip_sel].pt)), eta=ak.to_numpy(ak.flatten(flipped_electron[flip_sel].eta)), #phi = ak.to_numpy(ak.flatten(flipped_electron[flip_sel].phi)), #weight = ak.to_numpy(ak.flatten(ak_weight_flip)) ) return output
def test(): array = awkward1.Array([[{ "x": 0.0, "y": [] }, { "x": 1.1, "y": [1] }, { "x": 2.2, "y": [1, 2] }], [], [{ "x": 3.3, "y": [1, 2, None, 3] }, False, False, True, { "x": 4.4, "y": [1, 2, None, 3, 4] }]]) assert awkward1.full_like(array, 12.3).tolist() == [[{ "x": 12.3, "y": [] }, { "x": 12.3, "y": [12] }, { "x": 12.3, "y": [12, 12] }], [], [{ "x": 12.3, "y": [12, 12, None, 12] }, True, True, True, { "x": 12.3, "y": [12, 12, None, 12, 12] }]] assert awkward1.zeros_like(array).tolist() == [[{ "x": 0.0, "y": [] }, { "x": 0.0, "y": [0] }, { "x": 0.0, "y": [0, 0] }], [], [{ "x": 0.0, "y": [0, 0, None, 0] }, False, False, False, { "x": 0.0, "y": [0, 0, None, 0, 0] }]] assert awkward1.ones_like(array).tolist() == [[{ "x": 1.0, "y": [] }, { "x": 1.0, "y": [1] }, { "x": 1.0, "y": [1, 1] }], [], [{ "x": 1.0, "y": [1, 1, None, 1] }, True, True, True, { "x": 1.0, "y": [1, 1, None, 1, 1] }]] array = awkward1.Array([["one", "two", "three"], [], ["four", "five"]]) assert awkward1.full_like( array, "hello").tolist() == [["hello", "hello", "hello"], [], ["hello", "hello"]] assert awkward1.full_like(array, 1).tolist() == [["1", "1", "1"], [], ["1", "1"]] assert awkward1.full_like(array, 0).tolist() == [["0", "0", "0"], [], ["0", "0"]] assert awkward1.ones_like(array).tolist() == [["1", "1", "1"], [], ["1", "1"]] assert awkward1.zeros_like(array).tolist() == [["", "", ""], [], ["", ""]] array = awkward1.Array([[b"one", b"two", b"three"], [], [b"four", b"five"]]) assert awkward1.full_like( array, b"hello").tolist() == [[b"hello", b"hello", b"hello"], [], [b"hello", b"hello"]] assert awkward1.full_like(array, 1).tolist() == [[b"1", b"1", b"1"], [], [b"1", b"1"]] assert awkward1.full_like(array, 0).tolist() == [[b"0", b"0", b"0"], [], [b"0", b"0"]] assert awkward1.ones_like(array).tolist() == [[b"1", b"1", b"1"], [], [b"1", b"1"]] assert awkward1.zeros_like(array).tolist() == [[b"", b"", b""], [], [b"", b""]]