From ece30ebb596f99c1823f21ec712702c1cd1e12fc Mon Sep 17 00:00:00 2001 From: Billy Date: Thu, 3 Oct 2024 07:13:59 -0700 Subject: [PATCH] add: semiboosted HLT and event selection --- src/HH4b/processors/bbbbSkimmer.py | 112 ++++++++++++++++++++++++++--- 1 file changed, 103 insertions(+), 9 deletions(-) diff --git a/src/HH4b/processors/bbbbSkimmer.py b/src/HH4b/processors/bbbbSkimmer.py index 0bb50908..7eb7c1da 100644 --- a/src/HH4b/processors/bbbbSkimmer.py +++ b/src/HH4b/processors/bbbbSkimmer.py @@ -142,6 +142,14 @@ class bbbbSkimmer(SkimmerABC): "dr_leptons": 0.4, } + semi_boosted_ak4jets_selection = { + "pt": 30, + "eta_max": 2.5, + "id": "tight", + "dr_fatjets": 0.0, + "dr_leptons": 0.4, + } + ak4_bjet_lepton_selection = { # noqa: RUF012 "electron_pt": 5, "muon_pt": 7, @@ -199,6 +207,53 @@ def __init__( "AK8PFJet420_MassSD30", ], }, + # TODO: add semiboosted HLT + "semiboosted": { + "2018": [ + "PFJet500", + "AK8PFJet500", + "AK8PFJet360_TrimMass30", + "AK8PFJet380_TrimMass30", + "AK8PFJet400_TrimMass30", + "AK8PFHT750_TrimMass50", + "AK8PFHT800_TrimMass50", + "PFHT1050", + ], + "2022": [ + "AK8PFJet250_SoftDropMass40_PFAK8ParticleNetBB0p35", + "AK8PFJet425_SoftDropMass40", + # resolved + 'QuadPFJet70_50_40_35_PFBTagParticleNet_2BTagSum0p65', + ], + "2022EE": [ + "AK8PFJet250_SoftDropMass40_PFAK8ParticleNetBB0p35", + "AK8PFJet425_SoftDropMass40", + # resolved + 'QuadPFJet70_50_40_35_PFBTagParticleNet_2BTagSum0p65', + ], + "2023": [ + "AK8PFJet250_SoftDropMass40_PFAK8ParticleNetBB0p35", + "AK8PFJet230_SoftDropMass40_PNetBB0p06", + "AK8PFJet230_SoftDropMass40", + "AK8PFJet400_SoftDropMass40", + "AK8PFJet425_SoftDropMass40", + "AK8PFJet400_SoftDropMass40", + "AK8PFJet420_MassSD30", + # resolved + 'PFHT280_QuadPFJet30_PNet2BTagMean0p55', + ], + "2023BPix": [ + "AK8PFJet250_SoftDropMass40_PFAK8ParticleNetBB0p35", + "AK8PFJet230_SoftDropMass40_PNetBB0p06", + "AK8PFJet230_SoftDropMass40", + "AK8PFJet400_SoftDropMass40", + "AK8PFJet425_SoftDropMass40", + "AK8PFJet400_SoftDropMass40", + "AK8PFJet420_MassSD30", + # resolved + 'PFHT280_QuadPFJet30_PNet2BTagMean0p55', + ], + }, "semilep-tt": { "2022": [ "Ele32_WPTight_Gsf", @@ -303,6 +358,11 @@ def __init__( - >=2 AK8 jets with mSD>60 or mReg>60 - >=1 bb AK8 jets (ordered by TXbb) with TXbb > 0.8 - 0 veto leptons + semiboosted region: + - boosted and resolved HLT OR for both data and MC + - >=1 AK8 jet + - >=1 AK8 jet with pT>250 + - >=1 AK8 Jet with mSD>60 or mReg>60 semilep-tt region: - HLT OR for both data and MC - >=1 "good" isolated lepton with pT>50 @@ -413,7 +473,10 @@ def process(self, events: ak.Array): met = events.MET print("ak4 JECs", f"{time.time() - start:.2f}") - jets_sel = (jets.pt > 15) & (jets.isTight) & (abs(jets.eta) < 4.7) + if self._region == "semiboosted": + jets_sel = (jets.pt > 30) & (abs(jets.eta) < 2.5) & (jets.isTight) + else: + jets_sel = (jets.pt > 15) & (jets.isTight) & (abs(jets.eta) < 4.7) if not is_run3: jets_sel = jets_sel & ((jets.pt >= 50) | (jets.puId >= 6)) @@ -465,14 +528,24 @@ def process(self, events: ak.Array): ) # AK4 objects away from first two fatjets - ak4_jets_awayfromak8 = objects.ak4_jets_awayfromak8( - jets, - fatjets_xbb[:, :2], - events, - **self.ak4_bjet_selection, - **self.ak4_bjet_lepton_selection, - sort_by="nearest", - ) + if self._region == "semiboosted": + ak4_jets_awayfromak8 = objects.ak4_jets_awayfromak8( + jets, + fatjets_xbb[:, :2], + events, + **self.semi_boosted_ak4jets_selection, + **self.ak4_bjet_lepton_selection, + sort_by="nearest", + ) + else: + ak4_jets_awayfromak8 = objects.ak4_jets_awayfromak8( + jets, + fatjets_xbb[:, :2], + events, + **self.ak4_bjet_selection, + **self.ak4_bjet_lepton_selection, + sort_by="nearest", + ) # JMSR jmsr_vars = ( @@ -496,6 +569,8 @@ def process(self, events: ak.Array): # remove unnecessary ak4 gen variables for signal region if self._region == "signal": genVars = {key: val for (key, val) in genVars.items() if not key.startswith("ak4Jet")} + elif self._region == "semiboosted": + genVars = {key: val for (key, val) in genVars.items() if not key.startswith("ak4Jet")} # used for normalization to cross section below gen_selected = ( @@ -795,6 +870,25 @@ def process(self, events: ak.Array): # VBF veto cut (not now) # add_selection("vbf_veto", ~(cut_vbf), *selection_args) + elif self._region == "semiboosted": + # >= two AK8 jet, selection is same with boosted + # as skimmer selection is generally looser than AN selection + # more differences from boosted can be implemented in the postprocessors + add_selection("ak8_numjets", (ak.num(fatjets) >= 1), *selection_args) + + # AK4 jet noise filter, jet veto map, 2 ak4 jet pT > 30, eta<2.5, tight ID + add_selection("ak4_numjets", (ak.num(jets) >= 2), *selection_args) + + # >= two AK4 jets pass loose WP (Run3Summer22) + add_selection("ak4jet_btag", (ak.sum(jets.btagDeepFlavB >= 0.0583, axis=1) >=2), *selection_args) + + # 0 veto leptons + add_selection( + "0lep", + (ak.sum(veto_muon_sel, axis=1) == 0) & (ak.sum(veto_electron_sel, axis=1) == 0), + *selection_args, + ) + elif self._region == "pre-sel": # >=1 AK8 jets with pT>250 cut_pt = np.sum(ak8FatJetVars["ak8FatJetPt"] >= 250, axis=1) >= 1