ATLAS Offline Software
Loading...
Searching...
No Matches
TriggerBitsMakerTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
7#include "GaudiKernel/IAlgExecStateSvc.h"
8
9#include <algorithm>
10
11TriggerBitsMakerTool::TriggerBitsMakerTool(const std::string& type, const std::string& name, const IInterface* parent) :
12 base_class(type, name, parent){}
13
15
16 ATH_CHECK( m_finalChainDecisions.initialize() );
17 ATH_CHECK( m_HLTMenuKey.initialize() );
18
19 return StatusCode::SUCCESS;
20}
21
24 ATH_CHECK( hltMenuHandle.isValid() );
25 ATH_MSG_INFO("Configuring from " << m_HLTMenuKey << " with " << hltMenuHandle->size() << " chains");
26
27 m_mapping.clear();
28 m_largestBit = 0;
29 for (const TrigConf::Chain& ch : *hltMenuHandle) {
30 ATH_MSG_DEBUG( "Chain " << ch.name() << " will flip " << ch.counter() << " bit" );
31 ATH_CHECK(preInsertCheck(ch.name(), ch.counter()));
32 ATH_CHECK(hashConsistencyCheck(ch.name(), ch.namehash()));
33 m_mapping[ HLT::Identifier( ch.name() ).numeric() ] = ch.counter();
34 m_largestBit = std::max(m_largestBit, ch.counter());
35 }
36
37 // This block allows extra mappings to be supplied by python, e.g. for testing purposes
38 for (const auto& chainAndBit: m_extraChainToBit ) {
39 struct { std::string chain; uint32_t bit; } conf { chainAndBit.first, chainAndBit.second };
40 ATH_MSG_DEBUG( "Extra Chain " << conf.chain << " will flip " << conf.bit << " bit" );
41 ATH_CHECK(preInsertCheck(conf.chain, conf.bit));
42 m_mapping[ HLT::Identifier( conf.chain ).numeric() ] = conf.bit;
43 m_largestBit = std::max(m_largestBit, conf.bit);
44 }
45
46 return StatusCode::SUCCESS;
47}
48
49
50StatusCode TriggerBitsMakerTool::hashConsistencyCheck(const std::string& chain, const size_t hash) const {
51 if (HLT::Identifier( chain ).numeric() != hash) {
52 ATH_MSG_ERROR("Inconsistent hashes found for chain:" << chain << ", from Python:" << hash
53 << ", from C++:" << HLT::Identifier( chain ).numeric());
54 return StatusCode::FAILURE;
55 }
56 return StatusCode::SUCCESS;
57}
58
59StatusCode TriggerBitsMakerTool::preInsertCheck(const std::string& chain, const uint32_t bit) const {
60 const auto checkIt = std::find_if(
61 m_mapping.begin(), m_mapping.end(),
62 [&](const std::pair<TrigCompositeUtils::DecisionID, uint32_t>& m) { return m.second == bit; }
63 );
64 if (checkIt != m_mapping.end()) {
65 ATH_MSG_ERROR( "Multiple chains " << HLT::Identifier(checkIt->first)
66 << " and " << chain << " are both configured with ChainCounter:" << bit);
67 return StatusCode::FAILURE;
68 }
69 if (chain.empty()) {
70 ATH_MSG_ERROR( "Trying to register an empty string as a Chain." );
71 return StatusCode::FAILURE;
72 }
73 return StatusCode::SUCCESS;
74}
75
76StatusCode TriggerBitsMakerTool::getBits(boost::dynamic_bitset<uint32_t>& passRaw,
77 boost::dynamic_bitset<uint32_t>& prescaled,
78 const EventContext& ctx) const
79{
80 using namespace TrigCompositeUtils;
81
82 passRaw.clear();
83 prescaled.clear();
84
85 auto chainsHandle = SG::makeHandle(m_finalChainDecisions, ctx);
86 if (!chainsHandle.isValid()) {
87 SmartIF<IAlgExecStateSvc> aess = svcLoc()->service<IAlgExecStateSvc>("AlgExecStateSvc", false);
88 if (aess.isValid() && aess->eventStatus(ctx) != EventStatus::Success) {
89 ATH_MSG_WARNING("Failed event, " << m_finalChainDecisions.key() << " is unavailable. Skipping trigger bits making.");
90 return StatusCode::SUCCESS;
91 }
92 ATH_MSG_ERROR("Unable to read in the " << m_finalChainDecisions.key() << " from the DecisionSummaryMakerAlg");
93 return StatusCode::FAILURE;
94 }
95
96 passRaw.resize(m_largestBit + 1);
97 prescaled.resize(m_largestBit + 1);
98
99 const Decision* HLTPassRaw = nullptr;
100 const Decision* HLTPrescaled = nullptr;
101
102 DecisionIDContainer passRawIDs;
103 DecisionIDContainer prescaledIDs;
104
105 // Read the sets of chain IDs
106 for (const Decision* decisionObject : *chainsHandle) {
107 // Collect all decisions (IDs of passed/prescaled chains) from named decisionObjects
108 if (decisionObject->name() == TrigCompositeUtils::summaryPassNodeName()) {
109 HLTPassRaw = decisionObject;
110 } else if (decisionObject->name() == TrigCompositeUtils::summaryPrescaledNodeName()) {
111 HLTPrescaled = decisionObject;
112 }
113 if (HLTPassRaw != nullptr && HLTPrescaled != nullptr) {
114 break;
115 }
116 }
117
118 ATH_CHECK(HLTPassRaw != nullptr);
119 ATH_CHECK(HLTPrescaled != nullptr);
120
121 decisionIDs(HLTPassRaw, passRawIDs);
122 decisionIDs(HLTPrescaled, prescaledIDs);
123
124 for ( DecisionID chain: passRawIDs ) {
125 ATH_CHECK(setBit(chain, passRaw));
126 }
127
128 for ( DecisionID chain: prescaledIDs ) {
129 ATH_CHECK(setBit(chain, prescaled));
130 }
131
132 return StatusCode::SUCCESS;
133
134}
135
136StatusCode TriggerBitsMakerTool::fill( HLT::HLTResultMT& resultToFill, const EventContext& ctx ) const {
137
138 {
139 boost::dynamic_bitset<uint32_t> passRaw;
140 boost::dynamic_bitset<uint32_t> prescaled;
141
142 ATH_CHECK(getBits(passRaw, prescaled, ctx));
143 resultToFill.setHltBits(passRaw, prescaled);
144 }
145
146 if ( msgLvl( MSG::DEBUG ) ) {
147 const boost::dynamic_bitset<uint32_t>& passRawBits = resultToFill.getHltPassRawBits();
148 std::vector<uint32_t> bitsTemp(passRawBits.num_blocks());
149 boost::to_block_range(passRawBits, bitsTemp.begin());
150 ATH_MSG_VERBOSE("HLT result now has " << bitsTemp.size() << " words with HLT pass raw bits:");
151 for (const auto& w : bitsTemp) ATH_MSG_VERBOSE("0x" << MSG::hex << w << MSG::dec);
152 //
153 const boost::dynamic_bitset<uint32_t>& prescaleBits = resultToFill.getHltPrescaledBits();
154 boost::to_block_range(prescaleBits, bitsTemp.begin());
155 ATH_MSG_VERBOSE("HLT result now has " << bitsTemp.size() << " words with HLT prescale bits:");
156 for (const auto& w : bitsTemp) ATH_MSG_VERBOSE("0x" << MSG::hex << w << MSG::dec);
157 //
158 const std::vector<uint32_t>& words = resultToFill.getHltBitsAsWords();
159 ATH_MSG_DEBUG("HLT result now has " << words.size() << " words with the final trigger bits:");
160 for (const uint32_t w : words) ATH_MSG_DEBUG("0x" << MSG::hex << w << MSG::dec);
161 }
162
163 return StatusCode::SUCCESS;
164
165}
166
168 boost::dynamic_bitset<uint32_t>& resultToFill) const
169{
170 // Ignore per-leg IDs, only use chain-IDs
172 return StatusCode::SUCCESS;
173 }
174
175 auto mappingIter = m_mapping.find( chain );
176 // each chain has to have the counter
177 if( mappingIter == m_mapping.end() ) {
178 ATH_MSG_ERROR("Each chain has to have the bit/counter associated whereas the " << HLT::Identifier( chain ) << " does not" );
179 return StatusCode::FAILURE;
180 }
181 const int chainBitPosition = mappingIter->second;
182 ATH_MSG_DEBUG("Setting bit " << chainBitPosition << " corresponding to chain "<< HLT::Identifier(chain));
183 if (resultToFill.test(chainBitPosition)) {
184 ATH_MSG_WARNING(HLT::Identifier(chain) << " is setting its trigger bit " << chainBitPosition << " more than once");
185 }
186 resultToFill.set(chainBitPosition);
187 return StatusCode::SUCCESS;
188}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
unsigned int DecisionID
std::set< DecisionID > DecisionIDContainer
void decisionIDs(const Decision *d, DecisionIDContainer &id)
Extracts DecisionIDs stored in the Decision object.
A container class for data required to build online output from HLT.
Definition HLTResultMT.h:38
void setHltBits(const boost::dynamic_bitset< uint32_t > &passRawBitset, const boost::dynamic_bitset< uint32_t > &prescaledBitset)
Replace both HLT pass raw and prescaled bits with the given bitsets.
const std::vector< uint32_t > & getHltBitsAsWords() const
Const-getter for HLT bits as uint32_t array. Ordering: PassRaw, Prescaled.
const boost::dynamic_bitset< uint32_t > & getHltPassRawBits() const
Const-getter for HLT pass raw bits.
const boost::dynamic_bitset< uint32_t > & getHltPrescaledBits() const
Const-getter for HLT prescaled bits.
TrigCompositeUtils::DecisionID numeric() const
numeric ID
virtual bool isValid() override final
Can the handle be successfully dereferenced?
ChainToBitMap m_mapping
Mapping of each chain's hash ID to its chain counter.
TriggerBitsMakerTool(const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode start() override
SG::ReadHandleKey< TrigCompositeUtils::DecisionContainer > m_finalChainDecisions
StatusCode preInsertCheck(const std::string &chain, const uint32_t bit) const
Check that no existing key maps to a given value and that the string is not empty.
virtual StatusCode getBits(boost::dynamic_bitset< uint32_t > &passRaw, boost::dynamic_bitset< uint32_t > &prescaled, const EventContext &ctx) const override
StatusCode setBit(const TrigCompositeUtils::DecisionID chain, boost::dynamic_bitset< uint32_t > &resultToFill) const
Set to 1 the bit correspinding to 'chain' in 'resultToFill'.
virtual StatusCode fill(HLT::HLTResultMT &resultToFill, const EventContext &ctx) const override
SG::ReadHandleKey< TrigConf::HLTMenu > m_HLTMenuKey
Gaudi::Property< std::map< std::string, uint32_t > > m_extraChainToBit
StatusCode hashConsistencyCheck(const std::string &chain, const size_t hash) const
Check that a chain's hash in the menu JSON (via python) agrees with the C++ implementation.
virtual StatusCode initialize() override
uint32_t m_largestBit
Largest chain counter hence largest bit needed to be stored in result bitmap.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
const std::string & summaryPrescaledNodeName()
unsigned int DecisionID
const std::string & summaryPassNodeName()
bool isLegId(const HLT::Identifier &legIdentifier)
Recognise whether the chain ID is a leg ID.