@@ -60,7 +60,7 @@ class L1TriggerResultsConverter : public edm::stream::EDProducer<> {
6060
6161 // ----------member data ---------------------------
6262 const bool legacyL1_;
63- const bool store_unprefireable_bit_ ;
63+ const bool store_unprefireable_bits_ ;
6464 const edm::EDGetTokenT<L1GlobalTriggerReadoutRecord> tokenLegacy_;
6565 const edm::EDGetTokenT<GlobalAlgBlkBxCollection> token_;
6666 const edm::EDGetTokenT<GlobalExtBlkBxCollection> token_ext_;
@@ -77,12 +77,12 @@ class L1TriggerResultsConverter : public edm::stream::EDProducer<> {
7777//
7878L1TriggerResultsConverter::L1TriggerResultsConverter (const edm::ParameterSet& params)
7979 : legacyL1_(params.getParameter<bool >(" legacyL1" )),
80- store_unprefireable_bit_ (!legacyL1_ ? params.getParameter<bool >(" storeUnprefireableBit " ) : false),
80+ store_unprefireable_bits_ (!legacyL1_ ? params.getParameter<bool >(" storeUnprefireableBits " ) : false),
8181 tokenLegacy_(legacyL1_ ? consumes<L1GlobalTriggerReadoutRecord>(params.getParameter<edm::InputTag>(" src" ))
8282 : edm::EDGetTokenT<L1GlobalTriggerReadoutRecord>()),
8383 token_(!legacyL1_ ? consumes<GlobalAlgBlkBxCollection>(params.getParameter<edm::InputTag>(" src" ))
8484 : edm::EDGetTokenT<GlobalAlgBlkBxCollection>()),
85- token_ext_(store_unprefireable_bit_
85+ token_ext_(store_unprefireable_bits_
8686 ? consumes<GlobalExtBlkBxCollection>(params.getParameter<edm::InputTag>(" src_ext" ))
8787 : edm::EDGetTokenT<GlobalExtBlkBxCollection>()),
8888 l1gtmenuToken_(esConsumes<edm::Transition::BeginRun>()),
@@ -117,29 +117,35 @@ void L1TriggerResultsConverter::beginRun(edm::Run const&, edm::EventSetup const&
117117 names_.push_back (keyval.first );
118118 indices_.push_back (keyval.second .getIndex ());
119119 }
120- if (store_unprefireable_bit_)
121- names_.push_back (" L1_UnprefireableEvent" );
120+ if (store_unprefireable_bits_) {
121+ names_.push_back (" L1_UnprefireableEvent_TriggerRules" );
122+ names_.push_back (" L1_UnprefireableEvent_FirstBxInTrain" );
123+ }
122124 }
123125}
124126
125127// ------------ method called to produce the data ------------
126128
127129void L1TriggerResultsConverter::produce (edm::Event& iEvent, const edm::EventSetup& iSetup) {
128130 const std::vector<bool >* wordp = nullptr ;
129- bool unprefireable_bit = false ;
131+ bool unprefireable_bit_triggerrules = false ;
132+ bool unprefireable_bit_firstbxintrain = false ;
133+
130134 if (!legacyL1_) {
131135 const auto & resultsProd = iEvent.get (token_);
132136 if (not resultsProd.isEmpty (0 )) {
133137 wordp = &resultsProd.at (0 , 0 ).getAlgoDecisionFinal ();
134138 }
135- if (store_unprefireable_bit_ ) {
139+ if (store_unprefireable_bits_ ) {
136140 auto handleExtResults = iEvent.getHandle (token_ext_);
137141 if (handleExtResults.isValid ()) {
138142 if (not handleExtResults->isEmpty (0 )) {
139- unprefireable_bit = handleExtResults->at (0 , 0 ).getExternalDecision (GlobalExtBlk::maxExternalConditions - 1 );
143+ // 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).
144+ unprefireable_bit_triggerrules =
145+ handleExtResults->at (0 , 0 ).getExternalDecision (GlobalExtBlk::maxExternalConditions - 1 );
140146 }
141147 } else {
142- LogDebug (" Unprefirable bit not found, always set to false" );
148+ LogDebug (" Unprefirable bit (trigger rules) not found, always set to false" );
143149 }
144150 }
145151 } else {
@@ -155,9 +161,22 @@ void L1TriggerResultsConverter::produce(edm::Event& iEvent, const edm::EventSetu
155161 if (not mask_.empty ())
156162 result &= (mask_.at (index) != 0 );
157163 l1bitsAsHLTStatus[nidx] = edm::HLTPathStatus (result ? edm::hlt::Pass : edm::hlt::Fail);
164+ // Stores the unprefirable event decision corresponding to events in the first bx of a train.
165+ // In 2022/2023 the bx before that was manually masked.
166+ // Technically this was done by enabling the L1_FirstBunchBeforeTrain bit in the L1 menu, and vetoing that bit after L1 Final OR is evaluated.
167+ if (names_[nidx] == " L1_FirstBunchBeforeTrain" && !legacyL1_) {
168+ const auto & resultsProd = iEvent.get (token_);
169+ if (!(&resultsProd)->isEmpty (-1 )) {
170+ unprefireable_bit_firstbxintrain = (&resultsProd)->begin (-1 )->getAlgoDecisionFinal (index);
171+ }
172+ }
173+ }
174+ if (store_unprefireable_bits_) {
175+ l1bitsAsHLTStatus[indices_size] =
176+ edm::HLTPathStatus (unprefireable_bit_triggerrules ? edm::hlt::Pass : edm::hlt::Fail);
177+ l1bitsAsHLTStatus[indices_size + 1 ] =
178+ edm::HLTPathStatus (unprefireable_bit_firstbxintrain ? edm::hlt::Pass : edm::hlt::Fail);
158179 }
159- if (store_unprefireable_bit_)
160- l1bitsAsHLTStatus[indices_size] = edm::HLTPathStatus (unprefireable_bit ? edm::hlt::Pass : edm::hlt::Fail);
161180 // mimic HLT trigger bits for L1
162181 auto out = std::make_unique<edm::TriggerResults>(l1bitsAsHLTStatus, names_);
163182 iEvent.put (std::move (out));
@@ -169,8 +188,8 @@ void L1TriggerResultsConverter::fillDescriptions(edm::ConfigurationDescriptions&
169188 desc.add <bool >(" legacyL1" )->setComment (" is legacy L1" );
170189 desc.add <edm::InputTag>(" src" )->setComment (
171190 " L1 input (L1GlobalTriggerReadoutRecord if legacy, GlobalAlgBlkBxCollection otherwise)" );
172- desc.add <bool >(" storeUnprefireableBit " , false )
173- ->setComment (" Activate storage of L1 unprefireable bit (needs L1 external decision input)" );
191+ desc.add <bool >(" storeUnprefireableBits " , false )
192+ ->setComment (" Activate storage of L1 unprefireable bits (needs L1 external decision input)" );
174193 desc.add <edm::InputTag>(" src_ext" , edm::InputTag (" " ))
175194 ->setComment (" L1 external decision input (GlobalExtBlkBxCollection, only supported if not legacy" );
176195 descriptions.add (" L1TriggerResultsConverter" , desc);
0 commit comments