ATLAS Offline Software
TrigDecisionMakerMT.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /**************************************************************************
6  **
7  ** File: TrigDecisionMakerMT.h
8  **
9  ** Description: - Re-entrant Algorithm-derived class to run after the MT Trigger to create the
10  ** xAOD::TrigDecision object. Based on TrigDecisionMaker.cxx
11  **
12  * @author Tim Martin <Tim.Martin@cern.ch> - University of Warwick
13  **
14  ** Created: 16 July 2018
15  **
16  **************************************************************************/
17 
18 #include "TrigDecisionMakerMT.h"
19 
22 #include "Lvl1ResultAccessTool.h"
23 
25 
26 #include <boost/dynamic_bitset.hpp>
27 
28 TrigDec::TrigDecisionMakerMT::TrigDecisionMakerMT(const std::string &name, ISvcLocator *pSvcLocator)
29  : ::AthReentrantAlgorithm(name, pSvcLocator)
30 {}
31 
33 
36 {
37 
38  bool resultObjectIsUsed = true;
39  if (!m_bitsMakerTool.empty()) {
40  ATH_MSG_INFO("TrigDecisionMakerMT is setting up to run after the Trigger in a job with POOL output. "
41  "The TriggerBitsMakerTool will be used directly to create the xAOD::TrigDecision.");
42  ATH_CHECK( m_bitsMakerTool.retrieve() );
43  resultObjectIsUsed = false;
44  } else {
45  ATH_MSG_INFO("TrigDecisionMakerMT is setting up to read the trigger bits from trigger bytestream. "
46  "The HLTResultMT object will be used as the source of the trigger bits.");
47  }
48  ATH_CHECK( m_hltResultKeyIn.initialize(resultObjectIsUsed) ); // If false, this removes the ReadHandle
49 
50  ATH_CHECK( m_bgKey.initialize() );
51  ATH_CHECK( m_HLTMenuKey.initialize() );
52 
53  ATH_CHECK( m_ROIBResultKeyIn.initialize() );
54  ATH_CHECK( m_EventInfoKeyIn.initialize() );
55 
56  ATH_CHECK( m_trigDecisionKeyOut.initialize() );
57 
58  ATH_CHECK( m_lvl1Tool.retrieve() );
59 
60  return StatusCode::SUCCESS;
61 }
62 
65 {
66  // print out stats: used also to do regression tests
67  ATH_MSG_DEBUG ("=============================================");
68  ATH_MSG_DEBUG ("REGTEST Run summary:");
69  ATH_MSG_DEBUG ("REGTEST Events processed : " << m_nEvents);
70  ATH_MSG_DEBUG ("REGTEST Level 1 : passed = " << m_l1Passed);
71  ATH_MSG_DEBUG ("REGTEST HLT : passed = " << m_hltPassed);
72  ATH_MSG_DEBUG ("=============================================");
73 
74  return StatusCode::SUCCESS;
75 }
76 
78 TrigDec::TrigDecisionMakerMT::execute(const EventContext &context) const
79 {
80  using namespace TrigCompositeUtils;
81 
82  // increment event counter
83  m_nEvents++;
84 
85  std::unique_ptr<xAOD::TrigDecision> trigDec = std::make_unique<xAOD::TrigDecision>();
86  std::unique_ptr<xAOD::TrigDecisionAuxInfo> trigDecAux = std::make_unique<xAOD::TrigDecisionAuxInfo>();
87  trigDec->setStore(trigDecAux.get());
88 
89  SG::ReadHandle<TrigConf::HLTMenu> hltMenu(m_HLTMenuKey, context);
90  ATH_CHECK(hltMenu.isValid());
91  trigDec->setSMK(hltMenu->smk());
92 
93  if (m_doL1) {
94  const LVL1CTP::Lvl1Result* l1Result = nullptr;
95  ATH_CHECK(getL1Result(l1Result, context));
96 
97  trigDec->setTAV(l1Result->itemsAfterVeto());
98  trigDec->setTAP(l1Result->itemsAfterPrescale());
99  trigDec->setTBP(l1Result->itemsBeforePrescale());
100 
101  if (l1Result->isAccepted()) {
102  ++m_l1Passed;
103  }
104  }
105 
106  if (m_doHLT) {
107 
108  boost::dynamic_bitset<uint32_t> passRawBitset, prescaledBitset;
109 
110  if (m_bitsMakerTool.isSet()) {
111 
112  ATH_MSG_DEBUG ("MC Mode: Creating bits with TriggerBitsMakerTool");
113  ATH_CHECK(m_bitsMakerTool->getBits(passRawBitset, prescaledBitset, context));
114 
115  } else {
116 
117  ATH_MSG_DEBUG ("Data Mode: Reading bits from HLTResultMT");
118  SG::ReadHandle<HLT::HLTResultMT> hltResult = SG::makeHandle<HLT::HLTResultMT>(m_hltResultKeyIn, context);
119  ATH_CHECK(hltResult.isValid());
120 
121  passRawBitset = hltResult->getHltPassRawBits();
122  prescaledBitset = hltResult->getHltPrescaledBits();
123 
124  // Inspect error codes from event header
125  const std::vector<HLT::OnlineErrorCode> errorCodes = hltResult->getErrorCodes();
126  bool truncated = false;
127  uint32_t code = 0;
128  for (size_t i = 0; i < errorCodes.size(); ++i) {
129  truncated |= (errorCodes.at(i) == HLT::OnlineErrorCode::RESULT_TRUNCATION);
130  if (i == 0) {
131  code = static_cast<uint32_t>(errorCodes.at(0));
132  }
133  }
134 
135  // If the event header does not show any truncation check the individual HLT ROBs
136  // to cover the case of allowed result truncation (see ATR-27986).
137  //
138  // We only support one truncation status in the TrigDecision. So the convention is:
139  // 1) If the main HLT result is available, its status is reflected (e.g. Physics stream)
140  // 2) If not, we take the combined status of all other ROBs, but in practice there
141  // should only ever be one (TLA) ROB in a given stream.
142  if (!truncated) {
143  std::set<uint16_t> allModuleIds; // sorted(!) set of module IDs
144  for (const auto& itr : hltResult->getSerialisedData()) allModuleIds.insert(itr.first);
145 
146  for (uint16_t moduleId : allModuleIds) {
147  const std::vector<uint32_t>& status = hltResult->getRobStatus(moduleId);
148  if (status.size() > 1) { // status[0] is the generic eformat event status
149  truncated |= (status[1] == static_cast<uint32_t>(HLT::OnlineErrorCode::RESULT_TRUNCATION));
150  code |= status[1];
151  }
152  if (moduleId==0) break;
153  }
154  }
155 
156  trigDec->setEFErrorBits(code);
157  trigDec->setEFTruncated(truncated);
158  }
159 
160  ATH_MSG_DEBUG ("Number of HLT chains passed raw: " << passRawBitset.count());
161  ATH_MSG_DEBUG ("Number of HLT chains prescaled out: " << prescaledBitset.count());
162 
163  if (passRawBitset.any()) {
164  ++m_hltPassed;
165  }
166 
167  std::vector<uint32_t> passRaw, prescaled;
168 
169  passRaw.resize(passRawBitset.num_blocks());
170  prescaled.resize(prescaledBitset.num_blocks());
171 
172  boost::to_block_range(passRawBitset, passRaw.begin());
173  boost::to_block_range(prescaledBitset, prescaled.begin());
174 
175  // OFFLINE FIX TO P1 OPERATIONAL ISSUE 28th-31st July 2022
176  // [ATR-26036] These runs had an incomplete fix applied leading to incorrect prescale bits, prior runs in Run 3 had no presacled bits.
177  // Incorrect prescale bits will cause incorrect results from the Trig Decision Tool. Hence these need to be zeroed out (no prescale bits is better than wrong prescale bits)
178  static const std::set<unsigned> buggyPrescaleBitRuns = {429603, 429606, 429612, 429658, 429697, 429716};
179  const bool isBuggyPrescaleBitsRun = (std::find(buggyPrescaleBitRuns.begin(), buggyPrescaleBitRuns.end(), context.eventID().run_number()) != buggyPrescaleBitRuns.end());
180  if (isBuggyPrescaleBitsRun) {
181  ATH_MSG_DEBUG("T0 Trigger fix for 429603-429716 is deleting incorrect isPrescaled trigger bits decoded from the bytestream.");
182  for (size_t i = 0; i < prescaled.size(); ++i) {
183  prescaled.at(i) = 0;
184  }
185  }
186 
187  if (passRaw.size() != prescaled.size()) {
188  ATH_MSG_ERROR("Trigger bitsets are not all the same size! passRaw:"
189  << passRaw.size() << " prescaled:" << prescaled.size() );
190  return StatusCode::FAILURE;
191  }
192 
193  // Run 3 note: with only a two-level system, with no passthrough bit, no resurrection bit
194  // the raw-pass equates to the physics-pass.
195  trigDec->setEFPassedRaw(passRaw);
196  trigDec->setEFPassedPhysics(passRaw);
197  trigDec->setEFPrescaled(prescaled);
198 
199  }
200 
201  // get the bunch crossing id
202  const xAOD::EventInfo* eventInfo = SG::get(m_EventInfoKeyIn, context);
203  SG::ReadCondHandle<TrigConf::L1BunchGroupSet> bgkey(m_bgKey, context);
204  ATH_CHECK(bgkey.isValid());
205  const TrigConf::L1BunchGroupSet* l1bgs = *bgkey;
206  if (l1bgs) {
207  // We currently only support 8 bits/bunchgroups (ATR-24030)
208  trigDec->setBGCode( static_cast<char>(l1bgs->bgPattern(eventInfo->bcid())) );
209  }
210  else {
211  ATH_MSG_WARNING("Could not read " << m_bgKey);
212  }
213 
214  ATH_MSG_DEBUG ( "Run '" << eventInfo->runNumber()
215  << "'; Event '" << eventInfo->eventNumber()
216  << "'; BCID '" << eventInfo->bcid()
217  << "'; BG Code '" << trigDec->bgCode() << "'" ) ;
218 
219  ATH_MSG_DEBUG ("Decision object dump: " << *(trigDec.get()));
220  auto trigDecWriteHandle = SG::makeHandle( m_trigDecisionKeyOut, context );
221  ATH_CHECK( trigDecWriteHandle.record( std::move( trigDec ), std::move( trigDecAux ) ) );
222  ATH_MSG_DEBUG ("Recorded xAOD::TrigDecision to StoreGate with key = " << m_trigDecisionKeyOut.key());
223 
224  return StatusCode::SUCCESS;
225 }
226 
228 TrigDec::TrigDecisionMakerMT::getL1Result(const LVL1CTP::Lvl1Result *&result, const EventContext &context) const
229 {
230  SG::ReadHandle<ROIB::RoIBResult> roIBResult = SG::makeHandle<ROIB::RoIBResult>(m_ROIBResultKeyIn, context);
231  ATH_CHECK(roIBResult.isValid());
232 
233  std::vector< std::unique_ptr<LVL1CTP::Lvl1Item> > itemConfig = m_lvl1Tool->makeLvl1ItemConfig(context);
234 
235  if (roIBResult->cTPResult().isComplete()) {
236  m_lvl1Tool->createL1Items(itemConfig, *roIBResult, &result);
237  ATH_MSG_DEBUG ( "Built LVL1CTP::Lvl1Result from valid CTPResult.");
238  }
239 
240  if (result == nullptr) {
241  ATH_MSG_ERROR ( "Could not construct L1 result from roIBResult");
242  return StatusCode::FAILURE;
243  }
244 
245  return StatusCode::SUCCESS;
246 }
xAOD::TrigDecision_v1::setSMK
void setSMK(uint32_t value)
Set the Super Master Key describing this object.
xAOD::TrigDecision_v1::setEFPassedPhysics
void setEFPassedPhysics(const std::vector< uint32_t > &value)
Set the EF physics decision bits.
get_generator_info.result
result
Definition: get_generator_info.py:21
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
xAOD::EventInfo_v1::eventNumber
uint64_t eventNumber() const
The current event's event number.
TrigDecisionAuxInfo.h
TrigDec::TrigDecisionMakerMT::execute
virtual StatusCode execute(const EventContext &context) const override
Re-entrant execute to create the xAOD::TrigDecision.
Definition: TrigDecisionMakerMT.cxx:78
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
TrigConf::HLTMenu::smk
unsigned int smk() const
setter and getter for the supermasterkey
Definition: HLTMenu.cxx:41
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
xAOD::TrigDecision_v1::setEFTruncated
void setEFTruncated(bool value)
Set whether the EF result is truncated.
SG::ReadCondHandle::isValid
bool isValid()
Definition: ReadCondHandle.h:206
TrigDecisionMakerMT.h
xAOD::EventInfo_v1::runNumber
uint32_t runNumber() const
The current event's run number.
LVL1CTP::Lvl1Result::itemsBeforePrescale
const std::vector< uint32_t > & itemsBeforePrescale() const
Definition: Lvl1Result.h:55
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
Lvl1ResultAccessTool.h
LVL1CTP::Lvl1Result::itemsAfterVeto
const std::vector< uint32_t > & itemsAfterVeto() const
Definition: Lvl1Result.h:57
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:270
Lvl1Result.h
TrigDec::TrigDecisionMakerMT::~TrigDecisionMakerMT
~TrigDecisionMakerMT()
std deconstructor
Definition: TrigDecisionMakerMT.cxx:32
LVL1CTP::Lvl1Result::isAccepted
bool isAccepted() const
final LVL1 decision && isConfigured
Definition: Lvl1Result.cxx:19
HLT::HLTResultMT::getRobStatus
const std::vector< uint32_t > & getRobStatus(uint16_t moduleId) const
Status words for ROB with given moduleId.
Definition: HLTResultMT.cxx:226
HLT::HLTResultMT::getErrorCodes
const std::vector< HLT::OnlineErrorCode > getErrorCodes() const
Error codes getter (by value) - strips off the first bit-mask status word.
Definition: HLTResultMT.cxx:201
histSizes.code
code
Definition: histSizes.py:129
TrigDec::TrigDecisionMakerMT::finalize
virtual StatusCode finalize() override
std Gaudi finalize method -> print out statistics
Definition: TrigDecisionMakerMT.cxx:64
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:93
lumiFormat.i
int i
Definition: lumiFormat.py:85
SG::AuxElement::setStore
void setStore(const SG::IConstAuxStore *store)
Set the store associated with this object.
Definition: AuxElement.cxx:241
xAOD::TrigDecision_v1::setTAP
void setTAP(const std::vector< uint32_t > &value)
Set the Trigger After Prescale bits.
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
xAOD::TrigDecision_v1::setTBP
void setTBP(const std::vector< uint32_t > &value)
Set the Trigger Before Prescale bits.
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAOD::TrigDecision_v1::setTAV
void setTAV(const std::vector< uint32_t > &value)
Set the Trigger After Veto bits.
TrigDec::TrigDecisionMakerMT::getL1Result
StatusCode getL1Result(const LVL1CTP::Lvl1Result *&result, const EventContext &context) const
retrieve LVL1 result (called in execute)
Definition: TrigDecisionMakerMT.cxx:228
TrigConf::L1BunchGroupSet
L1 board configuration.
Definition: L1BunchGroupSet.h:71
TrigConf::L1BunchGroupSet::bgPattern
bgPattern_t bgPattern(size_t bcid) const
Return word with bit-pattern of fired bunchgroups for given bcid.
Definition: L1BunchGroupSet.cxx:138
xAOD::TrigDecision_v1::setEFErrorBits
void setEFErrorBits(uint32_t value)
Set a summary of all errors that happened during the EF execution.
TrigDec::TrigDecisionMakerMT::initialize
virtual StatusCode initialize() override
std Gaudi initialize method -> read-in trigger configuration
Definition: TrigDecisionMakerMT.cxx:35
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
ROIB::RoIBResult::cTPResult
const CTPResult & cTPResult() const
Gets the CTP part of the L1 RDO.
Definition: RoIBResult.cxx:60
OnlineErrorCode.h
LVL1CTP::Lvl1Result
Definition: Lvl1Result.h:32
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
HLT::HLTResultMT::getSerialisedData
const std::unordered_map< uint16_t, std::vector< uint32_t > > & getSerialisedData() const
Serialised data getter.
Definition: HLTResultMT.cxx:147
xAOD::EventInfo_v1
Class describing the basic event information.
Definition: EventInfo_v1.h:43
xAOD::TrigDecision_v1::setEFPrescaled
void setEFPrescaled(const std::vector< uint32_t > &value)
Set the EF prescaled bits.
xAOD::TrigDecision_v1::bgCode
char bgCode() const
Get the bunch group code of the current event.
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
xAOD::TrigDecision_v1::setEFPassedRaw
void setEFPassedRaw(const std::vector< uint32_t > &value)
Set the EF passed-raw bits.
TrigCompositeUtils
Definition: Event/xAOD/xAODTrigger/xAODTrigger/TrigComposite.h:19
HLT::HLTResultMT::getHltPrescaledBits
const boost::dynamic_bitset< uint32_t > & getHltPrescaledBits() const
Const-getter for HLT prescaled bits.
Definition: HLTResultMT.cxx:95
xAOD::TrigDecision_v1::setBGCode
void setBGCode(char value)
Set the bunch group code of the current event.
HLT::OnlineErrorCode::RESULT_TRUNCATION
@ RESULT_TRUNCATION
merge.status
status
Definition: merge.py:17
TrigDec::TrigDecisionMakerMT::TrigDecisionMakerMT
TrigDecisionMakerMT(const std::string &name, ISvcLocator *pSvcLocator)
std Gaudi Algorithm constructor
Definition: TrigDecisionMakerMT.cxx:28
xAOD::EventInfo_v1::bcid
uint32_t bcid() const
The bunch crossing ID of the event.
SG::get
const T * get(const ReadHandleKey< T > &key)
Convenience function to retrieve an object given a ReadHandleKey.
LVL1CTP::Lvl1Result::itemsAfterPrescale
const std::vector< uint32_t > & itemsAfterPrescale() const
Definition: Lvl1Result.h:56
ROIB::CTPResult::isComplete
bool isComplete() const
returns true if object isValid() and data has the expected length
HLT::HLTResultMT::getHltPassRawBits
const boost::dynamic_bitset< uint32_t > & getHltPassRawBits() const
Const-getter for HLT pass raw bits.
Definition: HLTResultMT.cxx:90