def Method1a(self, tagged, untagged): ''' tagged: jet collection of tagged jets untagged: jet collection untagged jets effs: dictionary of the tagging efficiencies (1D yahist objects) btag_sf: coffea b-tag SF object ''' tagged_b = yahist_1D_lookup(self.effs['b'], tagged.pt) * (tagged.hadronFlavour == 5) tagged_c = yahist_1D_lookup(self.effs['c'], tagged.pt) * (tagged.hadronFlavour == 4) tagged_light = yahist_1D_lookup( self.effs['light'], tagged.pt) * (tagged.hadronFlavour == 0) tagged_SFs = self.btag_sf.eval('central', tagged.hadronFlavour, abs(tagged.eta), tagged.pt) untagged_b = yahist_1D_lookup( self.effs['b'], untagged.pt) * (untagged.hadronFlavour == 5) untagged_c = yahist_1D_lookup( self.effs['c'], untagged.pt) * (untagged.hadronFlavour == 4) untagged_light = yahist_1D_lookup( self.effs['light'], untagged.pt) * (untagged.hadronFlavour == 0) untagged_SFs = self.btag_sf.eval('central', untagged.hadronFlavour, abs(untagged.eta), untagged.pt) tagged_all = (tagged_b + tagged_c + tagged_light) untagged_all = (untagged_b + untagged_c + untagged_light) denom = ak.prod(tagged_all, axis=1) * ak.prod( (1 - untagged_all), axis=1) num = ak.prod(tagged_all * tagged_SFs, axis=1) * ak.prod( (1 - untagged_all * untagged_SFs), axis=1) return num / denom
def combine(eff, sf): # tagged SF = SF*eff / eff = SF tagged_sf = awkward1.prod(sf[passbtag], axis=-1) # untagged SF = (1 - SF*eff) / (1 - eff) untagged_sf = awkward1.prod( ((1 - sf * eff) / (1 - eff))[~passbtag], axis=-1) return awkward1.fill_none(tagged_sf * untagged_sf, 1.) # TODO: move None guard to coffea
def flip_weight(self, electron): f_1 = yahist_2D_lookup(self.ratio, electron.pt[:, 0:1], abs(electron.eta[:, 0:1])) f_2 = yahist_2D_lookup(self.ratio, electron.pt[:, 1:2], abs(electron.eta[:, 1:2])) # I'm using ak.prod and ak.sum to replace empty arrays by 1 and 0, respectively weight = ak.sum(f_1 / (1 - f_1), axis=1) * ak.prod( 1 - f_2 / (1 - f_2), axis=1) + ak.sum( f_2 / (1 - f_2), axis=1) * ak.prod(1 - f_1 / (1 - f_1), axis=1) return weight
def get(self, ele, mu): if self.year == 2016: ele_sf_reco = self.evaluator["ele_2016_reco"](ele[ele.pt > 20].eta, ele[ele.pt > 20].pt) ele_sf_reco_low = self.evaluator["ele_2016_reco_low"]( ele[ele.pt <= 20].eta, ele[ele.pt <= 20].pt) ele_sf_id = self.evaluator["ele_2016_id"](ele.eta + ele.deltaEtaSC, ele.pt) ele_sf_iso = self.evaluator["ele_2016_iso"](ele.eta + ele.deltaEtaSC, ele.pt) mu_sf_id = self.evaluator["mu_2016_id"](mu.pt, abs(mu.eta)) mu_sf_iso = self.evaluator["mu_2016_iso"](mu.pt, abs(mu.eta)) #sf = ele_sf_id.prod() * ele_sf_iso.prod() * ele_sf_reco.prod() * ele_sf_reco_low.prod() * mu_sf_id.prod() * mu_sf_iso.prod() sf = ak.prod(ele_sf_reco, axis=1) * ak.prod( ele_sf_reco_low, axis=1) * ele_sf_id.prod() * ele_sf_iso.prod( ) * mu_sf_id.prod() * mu_sf_iso.prod() #FIXME elif self.year == 2017: ele_sf_reco = self.evaluator["ele_2017_reco"](ele[ele.pt > 20].eta, ele[ele.pt > 20].pt) ele_sf_reco_low = self.evaluator["ele_2017_reco_low"]( ele[ele.pt <= 20].eta, ele[ele.pt <= 20].pt) ele_sf_id = self.evaluator["ele_2017_id"](ele.eta + ele.deltaEtaSC, ele.pt) ele_sf_iso = self.evaluator["ele_2017_iso"](ele.eta + ele.deltaEtaSC, ele.pt) mu_sf_id = self.evaluator["mu_2017_id"](mu.pt, abs(mu.eta)) mu_sf_iso = self.evaluator["mu_2017_iso"](mu.pt, abs(mu.eta)) #sf = ele_sf_id.prod() * ele_sf_iso.prod() * ele_sf_reco.prod() * ele_sf_reco_low.prod() * mu_sf_id.prod() * mu_sf_iso.prod() sf = ak.prod(ele_sf_reco, axis=1) * ak.prod( ele_sf_reco_low, axis=1) * ele_sf_id.prod() * ele_sf_iso.prod( ) * mu_sf_id.prod() * mu_sf_iso.prod() #FIXME elif self.year == 2018: ele_sf_reco = self.evaluator["ele_2018_reco"](ele.eta, ele.pt) ele_sf_id = self.evaluator["ele_2018_id"](ele.eta + ele.deltaEtaSC, ele.pt) ele_sf_iso = self.evaluator["ele_2018_iso"](ele.eta + ele.deltaEtaSC, ele.pt) mu_sf_id = self.evaluator["mu_2018_id"](mu.pt, abs(mu.eta)) mu_sf_iso = self.evaluator["mu_2018_iso"](abs(mu.eta), mu.pt) #sf = ele_sf_id.prod() * ele_sf_iso.prod() * ele_sf_reco.prod() * mu_sf_id.prod() * mu_sf_iso.prod() sf = ak.prod(ele_sf_reco, axis=1) * ak.prod( ele_sf_id, axis=1) * ak.prod(ele_sf_iso, axis=1) * ak.prod( mu_sf_id, axis=1) * ak.prod(mu_sf_iso, axis=1) return sf
def Method1a(self, tagged, untagged, b_direction='central', c_direction='central'): import numpy as np ''' tagged: jet collection of tagged jets untagged: jet collection untagged jets effs: dictionary of the tagging efficiencies (1D yahist objects) btag_sf: coffea b-tag SF object ''' tagged_b = yahist_1D_lookup(self.effs['b'], tagged.pt)*(tagged.hadronFlavour==5) tagged_c = yahist_1D_lookup(self.effs['c'], tagged.pt)*(tagged.hadronFlavour==4) tagged_light = yahist_1D_lookup(self.effs['light'], tagged.pt)*(tagged.hadronFlavour==0) tagged_SFs_b = self.btag_sf.eval(b_direction, tagged.hadronFlavour, abs(tagged.eta), tagged.pt ) tagged_SFs_c = self.btag_sf.eval(c_direction, tagged.hadronFlavour, abs(tagged.eta), tagged.pt ) tagged_SFs_light = self.btag_sf.eval(c_direction, tagged.hadronFlavour, abs(tagged.eta), tagged.pt ) SFs_c = ((tagged_c/tagged_c)*tagged_SFs_c) SFs_b = ((tagged_b/tagged_b)*tagged_SFs_b) SFs_light = ((tagged_light/tagged_light)*tagged_SFs_light) SFs_c = np.where(np.isnan(SFs_c), 0, SFs_c) SFs_b = np.where(np.isnan(SFs_b), 0, SFs_b) SFs_light = np.where(np.isnan(SFs_light), 0, SFs_light) tagged_SFs = SFs_b+SFs_c+SFs_light untagged_b = yahist_1D_lookup(self.effs['b'], untagged.pt)*(untagged.hadronFlavour==5) untagged_c = yahist_1D_lookup(self.effs['c'], untagged.pt)*(untagged.hadronFlavour==4) untagged_light = yahist_1D_lookup(self.effs['light'], untagged.pt)*(untagged.hadronFlavour==0) untagged_SFs_b = self.btag_sf.eval(b_direction, untagged.hadronFlavour, abs(untagged.eta), untagged.pt ) untagged_SFs_c = self.btag_sf.eval(c_direction, untagged.hadronFlavour, abs(untagged.eta), untagged.pt ) untagged_SFs_light = self.btag_sf.eval(c_direction, untagged.hadronFlavour, abs(untagged.eta), untagged.pt ) SFs_c = ((untagged_c/untagged_c)*untagged_SFs_c) SFs_b = ((untagged_b/untagged_b)*untagged_SFs_b) SFs_light = ((untagged_light/untagged_light)*untagged_SFs_light) SFs_c = np.where(np.isnan(SFs_c), 0, SFs_c) SFs_b = np.where(np.isnan(SFs_b), 0, SFs_b) SFs_light = np.where(np.isnan(SFs_light), 0, SFs_light) untagged_SFs = SFs_b+SFs_c+SFs_light tagged_all = (tagged_b+tagged_c+tagged_light) untagged_all = (untagged_b+untagged_c+untagged_light) denom = ak.prod(tagged_all, axis=1) * ak.prod((1-untagged_all), axis=1) num = ak.prod(tagged_all*tagged_SFs, axis=1) * ak.prod((1-untagged_all*untagged_SFs), axis=1) return num/denom
def get(self, ele, mu): if self.year == 2016: muonScaleFactor = yahist_2D_lookup(self.h_muonScaleFactor, mu.pt, np.abs(mu.eta)) trackingSF = yahist_1D_lookup(self.h_trackingSF, mu.eta) electronScaleFactor_legacy = yahist_2D_lookup(self.h_electronScaleFactor_legacy, ele.pt, ele.eta) electronScaleFactorReco_legacy = yahist_2D_lookup(self.h_electronScaleFactorReco_legacy, ele.pt, ele.eta) sf = ak.prod(muonScaleFactor, axis=1)*ak.prod(trackingSF, axis=1)*ak.prod(electronScaleFactor_legacy, axis=1)*ak.prod(electronScaleFactorReco_legacy, axis=1) return sf if self.year == 2017: muonScaleFactor_Medium = yahist_2D_lookup(self.h_muonScaleFactor_Medium, mu.pt, np.abs(mu.eta)) muonScaleFactor_RunBCDEF = yahist_2D_lookup(self.h_muonScaleFactor_RunBCDEF, mu.pt, np.abs(mu.eta)) electronScaleFactor_RunBCDEF = yahist_2D_lookup(self.h_electronScaleFactor_RunBCDEF, ele.pt, ele.eta) electronScaleFactorReco_RunBCDEF = yahist_2D_lookup(self.h_electronScaleFactorReco_RunBCDEF, ele.pt, ele.eta) sf = ak.prod(muonScaleFactor_Medium, axis=1)*ak.prod(muonScaleFactor_RunBCDEF, axis=1)*ak.prod(electronScaleFactor_RunBCDEF, axis=1)*ak.prod(electronScaleFactorReco_RunBCDEF, axis=1) return sf if self.year == 2018: muonScaleFactor_RunABCD = yahist_2D_lookup(self.h_muonScaleFactor_RunABCD, mu.pt, np.abs(mu.eta)) muonScaleFactor_Medium = yahist_2D_lookup(self.h_muonScaleFactor_Medium, mu.pt, np.abs(mu.eta)) electronScaleFactor_RunABCD = yahist_2D_lookup(self.h_electronScaleFactor_RunABCD, ele.pt, ele.eta) electronScaleFactorReco_RunABCD = yahist_2D_lookup(self.h_electronScaleFactorReco_RunABCD, ele.pt, ele.eta) sf = ak.prod(muonScaleFactor_RunABCD, axis=1)*ak.prod(muonScaleFactor_Medium, axis=1)*ak.prod(electronScaleFactor_RunABCD, axis=1)*ak.prod(electronScaleFactorReco_RunABCD, axis=1) return sf
def test_0166_IndexedOptionArray(): array = awkward1.Array([[2, 3, 5], None, [], [7, 11], None, [13], None, [17, 19]]) assert awkward1.to_list(awkward1.prod( array, axis=-1)) == [30, None, 1, 77, None, 13, None, 323] array = awkward1.Array([[[2, 3], [5]], None, [], [[7], [11]], None, [[13]], None, [[17, 19]]]) assert awkward1.to_list(awkward1.prod(array, axis=-1)) == [[6, 5], None, [], [7, 11], None, [13], None, [323]] array = awkward1.Array([[[2, 3], None, [5]], [], [[7], [11]], [[13]], [None, [17], [19]]]) awkward1.to_list(awkward1.prod(array, axis=-1)) == [[6, None, 5], [], [7, 11], [13], [None, 17, 19]] array = awkward1.Array([[6, None, 5], [], [7, 11], [13], [None, 17, 19]]) assert awkward1.to_list(awkward1.prod(array, axis=-1)) == [30, 1, 77, 13, 323]
def get(self, el, mu, meas='QCD'): if meas == 'QCD': el_key, mu_key = 'el_QCD_NC', 'mu_QCD' elif meas == 'TT': el_key, mu_key = 'el_TT', 'mu_TT' elif meas == 'data': el_key, mu_key = 'el_data', 'mu_data' n_lep = ak.num(el) + ak.num(mu) sign = (-1)**(n_lep + 1) el_fr = self.evaluator[el_key](el.conePt, np.abs(el.etaSC)) mu_fr = self.evaluator[mu_key](mu.conePt, np.abs(mu.eta)) fr = ak.concatenate([el_fr, mu_fr], axis=1) return ak.prod(fr, axis=1) * sign
def flip_ratio(self, lepton1, lepton2): """takes a dilepton event and weights it based on the odds that one of the leptons has a charge flip""" flip1 = yahist_2D_lookup(self.ratio, lepton1.pt, abs(lepton1.eta)) flip2 = yahist_2D_lookup(self.ratio, lepton2.pt, abs(lepton2.eta)) flip_rate1 = (ak.prod(flip1, axis=1) * ak.prod(1 / (1 - flip1), axis=1) * ak.prod(1 - flip2 / (1 - flip2), axis=1)) + ( ak.prod(flip2, axis=1) * ak.prod(1 / (1 - flip2), axis=1) * ak.prod(1 - flip1 / (1 - flip1), axis=1)) return flip_rate1
def test_0166_ByteMaskedArray(): content = awkward1.from_iter( [[2, 3, 5], [999], [], [7, 11], [], [13], [123, 999], [17, 19]], highlevel=False) mask = awkward1.layout.Index8( numpy.array([0, 1, 0, 0, 1, 0, 1, 0], dtype=numpy.int8)) array = awkward1.Array( awkward1.layout.ByteMaskedArray(mask, content, valid_when=False)) assert awkward1.to_list(array) == [[2, 3, 5], None, [], [7, 11], None, [13], None, [17, 19]] assert awkward1.to_list(awkward1.prod( array, axis=-1)) == [30, None, 1, 77, None, 13, None, 323] content = awkward1.from_iter([[[2, 3], [5]], [[999]], [], [[7], [11]], [], [[13]], [[123], [999]], [[17, 19]]], highlevel=False) mask = awkward1.layout.Index8( numpy.array([0, 1, 0, 0, 1, 0, 1, 0], dtype=numpy.int8)) array = awkward1.Array( awkward1.layout.ByteMaskedArray(mask, content, valid_when=False)) assert awkward1.to_list(array) == [[[2, 3], [5]], None, [], [[7], [11]], None, [[13]], None, [[17, 19]]] assert awkward1.to_list(awkward1.prod(array, axis=-1)) == [[6, 5], None, [], [7, 11], None, [13], None, [323]] content = awkward1.from_iter( [[2, 3], [999], [5], [7], [11], [13], [], [17], [19]], highlevel=False) mask = awkward1.layout.Index8( numpy.array([0, 1, 0, 0, 0, 0, 1, 0, 0], dtype=numpy.int8)) bytemasked = awkward1.layout.ByteMaskedArray(mask, content, valid_when=False) offsets = awkward1.layout.Index64( numpy.array([0, 3, 3, 5, 6, 9], dtype=numpy.int64)) array = awkward1.Array( awkward1.layout.ListOffsetArray64(offsets, bytemasked)) array = awkward1.Array([[[2, 3], None, [5]], [], [[7], [11]], [[13]], [None, [17], [19]]]) assert awkward1.to_list(awkward1.prod(array, axis=-1)) == [[6, None, 5], [], [7, 11], [13], [None, 17, 19]] content = awkward1.from_iter([6, None, 5, 7, 11, 13, None, 17, 19], highlevel=False) mask = awkward1.layout.Index8( numpy.array([0, 1, 0, 0, 0, 0, 1, 0, 0], dtype=numpy.int8)) bytemasked = awkward1.layout.ByteMaskedArray(mask, content, valid_when=False) offsets = awkward1.layout.Index64( numpy.array([0, 3, 3, 5, 6, 9], dtype=numpy.int64)) array = awkward1.Array( awkward1.layout.ListOffsetArray64(offsets, bytemasked)) assert awkward1.to_list(array) == [[6, None, 5], [], [7, 11], [13], [None, 17, 19]] assert awkward1.to_list(awkward1.prod(array, axis=-1)) == [30, 1, 77, 13, 323]
def get(self, ele, mu): if self.year == 2016: ele_sf_reco = self.evaluator["ele_2016_reco"](ele[ele.pt > 20].eta, ele[ele.pt > 20].pt) ele_sf_reco_low = self.evaluator["ele_2016_reco_low"]( ele[ele.pt <= 20].eta, ele[ele.pt <= 20].pt) ele_sf_loose = self.evaluator["ele_2016_loose"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) ele_sf_looseTTH = self.evaluator["ele_2016_looseTTH"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) ele_sf_tight = self.evaluator["ele_2016_tight"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) mu_sf_loose = self.evaluator["mu_2016_loose"](abs(mu.eta), mu.pt) mu_sf_tight = self.evaluator["mu_2016_tight"](abs(mu.eta), mu.pt) sf = ak.prod(ele_sf_reco, axis=1) * ak.prod( ele_sf_reco_low, axis=1) * ak.prod(ele_sf_loose, axis=1) * ak.prod( ele_sf_looseTTH, axis=1) * ak.prod( ele_sf_tight, axis=1) * ak.prod( mu_sf_loose, axis=1) * ak.prod(mu_sf_tight, axis=1) elif self.year == 2017: ele_sf_reco = self.evaluator["ele_2017_reco"](ele[ele.pt > 20].eta, ele[ele.pt > 20].pt) ele_sf_reco_low = self.evaluator["ele_2017_reco_low"]( ele[ele.pt <= 20].eta, ele[ele.pt <= 20].pt) ele_sf_loose = self.evaluator["ele_2017_loose"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) ele_sf_looseTTH = self.evaluator["ele_2017_looseTTH"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) ele_sf_tight = self.evaluator["ele_2017_tight"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) mu_sf_loose = self.evaluator["mu_2017_loose"](abs(mu.eta), mu.pt) mu_sf_tight = self.evaluator["mu_2017_tight"](abs(mu.eta), mu.pt) sf = ak.prod(ele_sf_reco, axis=1) * ak.prod( ele_sf_reco_low, axis=1) * ak.prod(ele_sf_loose, axis=1) * ak.prod( ele_sf_looseTTH, axis=1) * ak.prod( ele_sf_tight, axis=1) * ak.prod( mu_sf_loose, axis=1) * ak.prod(mu_sf_tight, axis=1) elif self.year == 2018: ele_sf_reco = self.evaluator["ele_2018_reco"](ele.eta, ele.pt) ele_sf_loose = self.evaluator["ele_2018_loose"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) ele_sf_looseTTH = self.evaluator["ele_2018_looseTTH"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) ele_sf_tight = self.evaluator["ele_2018_tight"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) mu_sf_loose = self.evaluator["mu_2018_loose"](abs(mu.eta), mu.pt) mu_sf_tight = self.evaluator["mu_2018_tight"](abs(mu.eta), mu.pt) sf = ak.prod(ele_sf_reco, axis=1) * ak.prod( ele_sf_loose, axis=1) * ak.prod( ele_sf_looseTTH, axis=1) * ak.prod( ele_sf_tight, axis=1) * ak.prod( mu_sf_loose, axis=1) * ak.prod(mu_sf_tight, axis=1) return sf
def get(self, ele, mu, variation='central'): if self.year == 2016: ele_sf_reco = self.evaluator["ele_2016_reco"](ele[ele.pt > 20].eta, ele[ele.pt > 20].pt) ele_sf_reco_low = self.evaluator["ele_2016_reco_low"]( ele[ele.pt <= 20].eta, ele[ele.pt <= 20].pt) ele_sf_loose = self.evaluator["ele_2016_loose"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) ele_sf_looseTTH = self.evaluator["ele_2016_looseTTH"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) ele_sf_tight = self.evaluator["ele_2016_tight"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) mu_sf_loose = self.evaluator["mu_2016_loose"](abs(mu.eta), mu.pt) mu_sf_tight = self.evaluator["mu_2016_tight"](abs(mu.eta), mu.pt) sf = ak.prod(ele_sf_reco, axis=1) * ak.prod( ele_sf_reco_low, axis=1) * ak.prod(ele_sf_loose, axis=1) * ak.prod( ele_sf_looseTTH, axis=1) * ak.prod( ele_sf_tight, axis=1) * ak.prod( mu_sf_loose, axis=1) * ak.prod(mu_sf_tight, axis=1) elif self.year == 2017: ele_sf_reco = self.evaluator["ele_2017_reco"](ele[ele.pt > 20].eta, ele[ele.pt > 20].pt) ele_sf_reco_low = self.evaluator["ele_2017_reco_low"]( ele[ele.pt <= 20].eta, ele[ele.pt <= 20].pt) ele_sf_loose = self.evaluator["ele_2017_loose"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) ele_sf_looseTTH = self.evaluator["ele_2017_looseTTH"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) ele_sf_tight = self.evaluator["ele_2017_tight"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) mu_sf_loose = self.evaluator["mu_2017_loose"](abs(mu.eta), mu.pt) mu_sf_tight = self.evaluator["mu_2017_tight"](abs(mu.eta), mu.pt) sf = ak.prod(ele_sf_reco, axis=1) * ak.prod( ele_sf_reco_low, axis=1) * ak.prod(ele_sf_loose, axis=1) * ak.prod( ele_sf_looseTTH, axis=1) * ak.prod( ele_sf_tight, axis=1) * ak.prod( mu_sf_loose, axis=1) * ak.prod(mu_sf_tight, axis=1) elif self.year == 2018: ele_sf_reco = self.evaluator["ele_2018_reco"](ele.eta, ele.pt) ele_sf_loose = self.evaluator["ele_2018_loose"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) ele_sf_looseTTH = self.evaluator["ele_2018_looseTTH"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) ele_sf_tight = self.evaluator["ele_2018_tight"]( abs(ele.eta + ele.deltaEtaSC), ele.pt) mu_sf_loose = self.evaluator["mu_2018_loose"](abs(mu.eta), mu.pt) mu_sf_tight = self.evaluator["mu_2018_tight"](abs(mu.eta), mu.pt) if not variation == 'central': ele_sf_tight_err1 = self.evaluator["ele_2018_tight_eta"]( abs(ele.eta + ele.deltaEtaSC)) ele_sf_tight_err2 = self.evaluator["ele_2018_tight_pt"](ele.pt) ele_sf_tight_err1 = ak.from_regular( ele_sf_tight_err1[:, :, np.newaxis]) ele_sf_tight_err2 = ak.from_regular( ele_sf_tight_err2[:, :, np.newaxis]) ele_sf_tight_err = ak.max(ak.concatenate( [ele_sf_tight_err1, ele_sf_tight_err2], axis=2), axis=2) mu_sf_tight_err1 = self.evaluator["mu_2018_tight_eta"](abs( mu.eta)) mu_sf_tight_err2 = self.evaluator["mu_2018_tight_pt"](mu.pt) mu_sf_tight_err1 = ak.from_regular( mu_sf_tight_err1[:, :, np.newaxis]) mu_sf_tight_err2 = ak.from_regular( mu_sf_tight_err2[:, :, np.newaxis]) mu_sf_tight_err = ak.max(ak.concatenate( [mu_sf_tight_err1, mu_sf_tight_err2], axis=2), axis=2) if variation == 'up': ele_sf_tight = ele_sf_tight * ele_sf_tight_err mu_sf_tight = mu_sf_tight * mu_sf_tight_err if variation == 'down': ele_sf_tight = ele_sf_tight / ele_sf_tight_err mu_sf_tight = mu_sf_tight / mu_sf_tight_err sf = ak.prod(ele_sf_reco, axis=1) * ak.prod( ele_sf_loose, axis=1) * ak.prod( ele_sf_looseTTH, axis=1) * ak.prod( ele_sf_tight, axis=1) * ak.prod( mu_sf_loose, axis=1) * ak.prod(mu_sf_tight, axis=1) return sf