diff --git a/PhysicsTools/NanoAOD/plugins/L1TriggerResultsConverter.cc b/PhysicsTools/NanoAOD/plugins/L1TriggerResultsConverter.cc index 7544cfa450b8f..d2778836fd9fd 100644 --- a/PhysicsTools/NanoAOD/plugins/L1TriggerResultsConverter.cc +++ b/PhysicsTools/NanoAOD/plugins/L1TriggerResultsConverter.cc @@ -60,7 +60,7 @@ class L1TriggerResultsConverter : public edm::stream::EDProducer<> { // ----------member data --------------------------- const bool legacyL1_; - const bool store_unprefireable_bit_; + const bool store_unprefireable_bits_; const edm::EDGetTokenT tokenLegacy_; const edm::EDGetTokenT token_; const edm::EDGetTokenT token_ext_; @@ -77,12 +77,12 @@ class L1TriggerResultsConverter : public edm::stream::EDProducer<> { // L1TriggerResultsConverter::L1TriggerResultsConverter(const edm::ParameterSet& params) : legacyL1_(params.getParameter("legacyL1")), - store_unprefireable_bit_(!legacyL1_ ? params.getParameter("storeUnprefireableBit") : false), + store_unprefireable_bits_(!legacyL1_ ? params.getParameter("storeUnprefireableBits") : false), tokenLegacy_(legacyL1_ ? consumes(params.getParameter("src")) : edm::EDGetTokenT()), token_(!legacyL1_ ? consumes(params.getParameter("src")) : edm::EDGetTokenT()), - token_ext_(store_unprefireable_bit_ + token_ext_(store_unprefireable_bits_ ? consumes(params.getParameter("src_ext")) : edm::EDGetTokenT()), l1gtmenuToken_(esConsumes()), @@ -117,8 +117,10 @@ void L1TriggerResultsConverter::beginRun(edm::Run const&, edm::EventSetup const& names_.push_back(keyval.first); indices_.push_back(keyval.second.getIndex()); } - if (store_unprefireable_bit_) - names_.push_back("L1_UnprefireableEvent"); + if (store_unprefireable_bits_) { + names_.push_back("L1_UnprefireableEvent_TriggerRules"); + names_.push_back("L1_UnprefireableEvent_FirstBxInTrain"); + } } } @@ -126,20 +128,24 @@ void L1TriggerResultsConverter::beginRun(edm::Run const&, edm::EventSetup const& void L1TriggerResultsConverter::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { const std::vector* wordp = nullptr; - bool unprefireable_bit = false; + bool unprefireable_bit_triggerrules = false; + bool unprefireable_bit_firstbxintrain = false; + if (!legacyL1_) { const auto& resultsProd = iEvent.get(token_); if (not resultsProd.isEmpty(0)) { wordp = &resultsProd.at(0, 0).getAlgoDecisionFinal(); } - if (store_unprefireable_bit_) { + if (store_unprefireable_bits_) { auto handleExtResults = iEvent.getHandle(token_ext_); if (handleExtResults.isValid()) { if (not handleExtResults->isEmpty(0)) { - unprefireable_bit = handleExtResults->at(0, 0).getExternalDecision(GlobalExtBlk::maxExternalConditions - 1); + //Stores the unprefirable event decision corresponding to trigger rules (e.g.: BX0 is unprefirable because BX-3 fired and therefore BX-2/-1 are masked). + unprefireable_bit_triggerrules = + handleExtResults->at(0, 0).getExternalDecision(GlobalExtBlk::maxExternalConditions - 1); } } else { - LogDebug("Unprefirable bit not found, always set to false"); + LogDebug("Unprefirable bit (trigger rules) not found, always set to false"); } } } else { @@ -155,9 +161,22 @@ void L1TriggerResultsConverter::produce(edm::Event& iEvent, const edm::EventSetu if (not mask_.empty()) result &= (mask_.at(index) != 0); l1bitsAsHLTStatus[nidx] = edm::HLTPathStatus(result ? edm::hlt::Pass : edm::hlt::Fail); + //Stores the unprefirable event decision corresponding to events in the first bx of a train. + //In 2022/2023 the bx before that was manually masked. + //Technically this was done by enabling the L1_FirstBunchBeforeTrain bit in the L1 menu, and vetoing that bit after L1 Final OR is evaluated. + if (names_[nidx] == "L1_FirstBunchBeforeTrain" && !legacyL1_) { + const auto& resultsProd = iEvent.get(token_); + if (!(&resultsProd)->isEmpty(-1)) { + unprefireable_bit_firstbxintrain = (&resultsProd)->begin(-1)->getAlgoDecisionFinal(index); + } + } + } + if (store_unprefireable_bits_) { + l1bitsAsHLTStatus[indices_size] = + edm::HLTPathStatus(unprefireable_bit_triggerrules ? edm::hlt::Pass : edm::hlt::Fail); + l1bitsAsHLTStatus[indices_size + 1] = + edm::HLTPathStatus(unprefireable_bit_firstbxintrain ? edm::hlt::Pass : edm::hlt::Fail); } - if (store_unprefireable_bit_) - l1bitsAsHLTStatus[indices_size] = edm::HLTPathStatus(unprefireable_bit ? edm::hlt::Pass : edm::hlt::Fail); //mimic HLT trigger bits for L1 auto out = std::make_unique(l1bitsAsHLTStatus, names_); iEvent.put(std::move(out)); @@ -169,8 +188,8 @@ void L1TriggerResultsConverter::fillDescriptions(edm::ConfigurationDescriptions& desc.add("legacyL1")->setComment("is legacy L1"); desc.add("src")->setComment( "L1 input (L1GlobalTriggerReadoutRecord if legacy, GlobalAlgBlkBxCollection otherwise)"); - desc.add("storeUnprefireableBit", false) - ->setComment("Activate storage of L1 unprefireable bit (needs L1 external decision input)"); + desc.add("storeUnprefireableBits", false) + ->setComment("Activate storage of L1 unprefireable bits (needs L1 external decision input)"); desc.add("src_ext", edm::InputTag("")) ->setComment("L1 external decision input (GlobalExtBlkBxCollection, only supported if not legacy"); descriptions.add("L1TriggerResultsConverter", desc); diff --git a/PhysicsTools/NanoAOD/python/triggerObjects_cff.py b/PhysicsTools/NanoAOD/python/triggerObjects_cff.py index 325f93f32bb14..57d77d566c28c 100644 --- a/PhysicsTools/NanoAOD/python/triggerObjects_cff.py +++ b/PhysicsTools/NanoAOD/python/triggerObjects_cff.py @@ -375,7 +375,7 @@ def AND(tokens): l1bits=cms.EDProducer("L1TriggerResultsConverter", src=cms.InputTag("gtStage2Digis"), legacyL1=cms.bool(False), - storeUnprefireableBit=cms.bool(True), + storeUnprefireableBits=cms.bool(True), src_ext=cms.InputTag("simGtExtUnprefireable")) triggerObjectTablesTask = cms.Task( unpackedPatTrigger,triggerObjectTable,l1bits)