ATLAS Offline Software
L1DataConsistencyChecker.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 // Local includes
7 // Trigger includes
9 #include "TrigConfData/L1Item.h"
11 // Athena includes
14 // System includes
15 #include <unordered_map>
16 #include <sstream>
17 
18 namespace{
19  // this can be constexpr in C++20
20  bool vectorContains(const std::vector<std::string>& vec, const std::string& str) {
21  return (std::find(vec.cbegin(),vec.cend(),str)!=vec.cend());
22  }
23 }
24 
25 // =============================================================================
29  if (!m_monTool.empty()) {
30  ATH_CHECK(m_monTool.retrieve());
31  }
32  return StatusCode::SUCCESS;
33 }
34 
35 // =============================================================================
38  ATH_CHECK(l1Menu.isValid());
40  ATH_CHECK(hltMenu.isValid());
41 
42  TrigConf::LogicParser logicParser;
43 
44  m_thresholdMap.clear();
45  m_thresholdNames.clear();
46  m_thresholdTypes.clear();
47  m_monitoredThresholds.clear();
48 
49  for (const TrigConf::Chain& chain : *hltMenu) {
50  try {
51  // For chains with multiple seeds, we cannot determine in this tool which seed passed and which didn't,
52  // so we need to skip these kinds of chains
53  if (chain.l1item().empty() || chain.l1item().find(',')!=std::string::npos) {continue;}
54 
55  TrigConf::L1Item item = l1Menu->item(chain.l1item());
56  std::map<std::string,unsigned int> thresholds = logicParser.parse(item.definition())->elementsCount();
57  for (const auto& [thrName, multiplicity] : thresholds) {
58  const TrigConf::L1Threshold& thr = l1Menu->threshold(thrName);
59  // Skip thresholds for which there are no TOBs, e.g. randoms
60  if (vectorContains(m_excludedThresholdTypes.value(), thr.type())) {
61  continue;
62  }
64  m_thresholdMap[chain.namehash()].insert({thrNameHash, multiplicity});
65  m_monitoredThresholds.insert(thrNameHash);
66  }
67  }
68  catch (const std::exception& ex) {
69  ATH_MSG_ERROR("Exception caught while parsing L1 thresholds for chain " << chain.name() << ": " << ex.what());
70  return StatusCode::FAILURE;
71  }
72  }
73 
74  for (const std::shared_ptr<TrigConf::L1Threshold>& thr : l1Menu->thresholds()) {
75  TrigCompositeUtils::DecisionID thrNameHash = HLT::Identifier(thr->name());
76  m_thresholdNames[thrNameHash] = thr->name();
77  m_thresholdTypes[thrNameHash] = thr->type();
78  }
79 
80  return StatusCode::SUCCESS;
81 }
82 
83 // =============================================================================
84 StatusCode L1DataConsistencyChecker::consistencyCheck(const HLT::IDVec& l1SeededChains, const EventContext& ctx) const {
85  auto monTimer = Monitored::Timer<std::chrono::duration<float, std::milli>>("TIME_consistencyCheck");
86  StatusCode sc = StatusCode::SUCCESS;
87 
88  // ---------------------------------------------------------------------------
89  // Get information from TOBs
90  // ---------------------------------------------------------------------------
91  std::ostringstream ssPassedThresholds; // ss for debug printouts, allocate before loop
92  std::unordered_map<TrigCompositeUtils::DecisionID, size_t> tobThresholdCounts; // {thrName hash, nTOBs passing thr}
93  std::unordered_set<std::string> overflowThresholdTypes; // threshold types for which overflow was detected
94  // Loop over threshold types
95  for (const auto& [thrType, decisionsKey] : m_thresholdToDecisionMap.value()) {
97  if (!decisions.isValid()) {
98  ATH_MSG_DEBUG("No DecisionContainer " << decisionsKey << " for threshold type " << thrType << " found in this event");
99  continue;
100  }
101  size_t idec{0};
102  // Loop over TOBs of the given threshold type (one decision = one TOB)
103  for (const TrigCompositeUtils::Decision* d : *decisions) {
104  std::vector<TrigCompositeUtils::DecisionID> passedThresholdIDs;
105  const bool hasDetail = d->getDetail("thresholds", passedThresholdIDs);
106  if (!hasDetail) {
107  ATH_MSG_ERROR("Detail \"thresholds\" missing from Decision in the container " << decisionsKey);
108  return StatusCode::FAILURE;
109  }
110  bool overflow{false};
111  if (d->hasDetail<char>("overflow")) {
112  overflow = static_cast<bool>(d->getDetail<char>("overflow"));
113  }
114  if (doDebug()) {ssPassedThresholds.str("");}
115  for (const TrigCompositeUtils::DecisionID thrNameHash : passedThresholdIDs) {
116  if (overflow) {
117  overflowThresholdTypes.insert(m_thresholdTypes.at(thrNameHash));
118  }
119  if (tobThresholdCounts.find(thrNameHash)==tobThresholdCounts.end()) {
120  tobThresholdCounts[thrNameHash] = 1;
121  }
122  else {
123  tobThresholdCounts[thrNameHash] += 1;
124  }
125  if (doDebug()) {
126  if (!ssPassedThresholds.str().empty()) ssPassedThresholds << ", ";
127  ssPassedThresholds << m_thresholdNames.at(thrNameHash);
128  }
129  }
130  if (doDebug()) {
131  namespace RoIDefs = HLTSeedingRoIToolDefs;
132  std::optional<RoIDefs::AnyRoIPointer> optTob = RoIDefs::roiFromLink(*d, TrigCompositeUtils::initialRecRoIString());
133  if (optTob.has_value()) {
134  const RoIDefs::AnyRoIPointer& tob = optTob.value();
135  ATH_MSG_DEBUG("Decision " << decisionsKey << "[" << idec << "] corresponds to TOB with word / et / eta / phi = 0x"
136  << MSG::hex << RoIDefs::roiWord(tob) << MSG::dec << " / " << RoIDefs::roiTobEt(tob)
137  << " / " << RoIDefs::roiEta(tob) << " / " << RoIDefs::roiPhi(tob));
138  } else {
139  ATH_MSG_DEBUG("Decision " << decisionsKey << "[" << idec << "] TOB type not supported by template code for "
140  << "debug printout of word / et / eta / phi");
141  }
142  ATH_MSG_DEBUG("Decision " << decisionsKey << "[" << idec << "] TOB passes " << passedThresholdIDs.size()
143  << " thresholds: " << ssPassedThresholds.str());
144  ++idec;
145  }
146  }
147  }
148 
149  // ---------------------------------------------------------------------------
150  // Get information from CTP
151  // ---------------------------------------------------------------------------
152  std::unordered_map<TrigCompositeUtils::DecisionID, size_t> ctpThresholdCounts; // {thrName hash, max CTP multiplicity}
153  // Loop over HLT chains activated by CTP
154  for (const TrigCompositeUtils::DecisionID chainID : l1SeededChains) {
155  const auto it = m_thresholdMap.find(chainID);
156  if (it==m_thresholdMap.end()) {
157  ATH_MSG_DEBUG("Cannot monitor chain " << chainID << " -> " << HLT::Identifier(chainID).name() << ", skipping");
158  continue;
159  }
160  const MultiplicityInfo& thresholds = it->second;
161  // Loop over all thresholds required to activate this chain
162  for (const auto& [thrNameHash, multiplicity] : thresholds) {
163  if (ctpThresholdCounts.find(thrNameHash)==ctpThresholdCounts.end()) {
164  ctpThresholdCounts[thrNameHash] = multiplicity;
165  }
166  else if (multiplicity > ctpThresholdCounts[thrNameHash]) {
167  ctpThresholdCounts[thrNameHash] = multiplicity;
168  }
169  }
170  }
171 
172  // ---------------------------------------------------------------------------
173  // Perform the consistency check
174  // ---------------------------------------------------------------------------
175  for (const auto& [thrNameHash, ctpCount] : ctpThresholdCounts) {
176  size_t tobCount{0};
177  bool tooFew{false};
178  const auto it = m_thresholdNames.find(thrNameHash);
179  if (it==m_thresholdNames.end()) {
180  ATH_MSG_ERROR("Threshold with hash " << thrNameHash << " not found in the hash->name map");
181  return StatusCode::FAILURE;
182  }
183  const std::string& thrName = it->second;
184  const std::string& thrType = m_thresholdTypes.at(thrNameHash);
185 
186  // Check if overflow was detected
187  bool overflow{overflowThresholdTypes.find(thrType)!=overflowThresholdTypes.end()};
188  if (overflow) {
189  ATH_MSG_DEBUG("Threshold " << thrName << " accepted by the CTP with multiplicity " << ctpCount
190  << " is flagged as overflow and thus may be missing TOBs");
191  }
192 
193  // True if no TOBs found for this threshold but CTP accepted
194  bool missing = (tobThresholdCounts.find(thrNameHash)==tobThresholdCounts.end());
195 
196  if (missing) {
197  if (overflow || !m_errorOnMissingTOB) {
198  ATH_MSG_WARNING("No TOBs found passing the threshold " << thrName
199  << " accepted by the CTP with multiplicity " << ctpCount
200  << (overflow ? ", likely due to overflow" : ""));
201 
202  } else {
203  ATH_MSG_ERROR("No TOBs found passing the threshold " << thrName
204  << " accepted by the CTP with multiplicity " << ctpCount);
205  sc = StatusCode::FAILURE;
206  }
207  }
208  else {
209  tobCount = tobThresholdCounts.at(thrNameHash);
210  // True if fewer TOBs found for this threshold than the multiplicity accepted by CTP
211  tooFew = (tobCount < ctpCount);
212  }
213 
214  if (tooFew) {
215  if (overflow || !m_errorOnMissingTOB) {
216  ATH_MSG_WARNING("Too few (" << tobCount << ") TOBs found passing the threshold " << thrName
217  << " accepted by the CTP with multiplicity " << ctpCount
218  << (overflow ? ", likely due to overflow" : ""));
219  } else {
220  ATH_MSG_ERROR("Too few (" << tobCount << ") TOBs found passing the threshold " << thrName
221  << " accepted by the CTP with multiplicity " << ctpCount);
222  sc = StatusCode::FAILURE;
223  }
224  }
225 
226  if (missing || tooFew) {
227  // Fill the histograms
228  Monitored::Scalar monMissingTOBsIncludingOverflow{"MissingTOBsIncludingOverflow", thrName};
229  if (overflow) {
230  Monitored::Group{m_monTool, monMissingTOBsIncludingOverflow};
231  }
232  else {
233  Monitored::Scalar monMissingTOBs{"MissingTOBs", thrName};
234  Monitored::Group{m_monTool, monMissingTOBs, monMissingTOBsIncludingOverflow};
235  }
236  }
237  else {
238  ATH_MSG_DEBUG("Check passed. Found " << tobCount << " TOBs passing the threshold " << thrName
239  << " accepted by the CTP with multiplicity " << ctpCount);
240  }
241  }
242 
243  // Fill extra histograms for debugging
244  for (const TrigCompositeUtils::DecisionID thrNameHash : m_monitoredThresholds) {
245  const auto ctpIt = ctpThresholdCounts.find(thrNameHash);
246  size_t ctpCount = (ctpIt==ctpThresholdCounts.cend()) ? 0 : ctpIt->second;
247  const auto tobIt = tobThresholdCounts.find(thrNameHash);
248  size_t tobCount = (tobIt==tobThresholdCounts.cend()) ? 0 : tobIt->second;
249  int tobMinusCtpCount = static_cast<int>(ctpCount) - static_cast<int>(tobCount); // negative when TOBs are missing
250  const std::string& thrName = m_thresholdNames.at(thrNameHash);
251 
252  Monitored::Scalar monThrName{"ThrName", thrName};
253  Monitored::Scalar monCtpCount{"CtpCount", ctpCount};
254  Monitored::Scalar monTobCount{"TobCount", tobCount};
255  Monitored::Scalar monTobMinusCtpCount{"TobMinusCtpCount", tobMinusCtpCount};
256  Monitored::Group{m_monTool, monThrName, monCtpCount, monTobCount, monTobMinusCtpCount};
257  }
258 
259  Monitored::Group(m_monTool, monTimer);
260  return sc;
261 }
ReadHandleKey.h
Property holding a SG store/key/clid from which a ReadHandle is made.
L1DataConsistencyChecker::m_thresholdNames
std::unordered_map< TrigCompositeUtils::DecisionID, std::string > m_thresholdNames
Definition: L1DataConsistencyChecker.h:63
L1DataConsistencyChecker::m_hltMenuKey
SG::ReadHandleKey< TrigConf::HLTMenu > m_hltMenuKey
Definition: L1DataConsistencyChecker.h:37
TrigDefs::Group
Group
Properties of a chain group.
Definition: GroupProperties.h:13
StateLessPT_NewConfig.proxy
proxy
Definition: StateLessPT_NewConfig.py:392
runLayerRecalibration.chain
chain
Definition: runLayerRecalibration.py:175
HLTSeedingRoIToolDefs::AnyRoIPointer
std::variant< const eFexEM::T_RoI *, const eFexTau::T_RoI *, const jFexFwdEl::T_RoI *, const jFexTau::T_RoI *, const jFexSRJet::T_RoI *, const jFexLRJet::T_RoI *, const gFexSRJet::T_RoI *, const Muon::T_RoI * > AnyRoIPointer
std::variant of const ptr to RoI types. Note identical types are only entered once in the template (e...
Definition: HLTSeedingRoIToolDefs.h:144
HLTSeedingRoIToolDefs::roiPhi
constexpr float roiPhi(const AnyRoIPointer &roi)
Definition: HLTSeedingRoIToolDefs.h:167
TrigCompositeUtils::DecisionID
unsigned int DecisionID
Definition: TrigComposite_v1.h:27
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
L1Item.h
TrigCompositeUtils.h
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
hist_file_dump.d
d
Definition: hist_file_dump.py:137
L1DataConsistencyChecker::start
virtual StatusCode start() override
Definition: L1DataConsistencyChecker.cxx:36
skel.it
it
Definition: skel.GENtoEVGEN.py:423
Monitored::Group
Group of local monitoring quantities and retain correlation when filling histograms
Definition: MonitoredGroup.h:54
L1DataConsistencyChecker::m_monTool
ToolHandle< GenericMonitoringTool > m_monTool
Definition: L1DataConsistencyChecker.h:42
TrigCompositeUtils::initialRecRoIString
const std::string & initialRecRoIString()
Definition: TrigCompositeUtilsRoot.cxx:874
xAOD::roiEta
setTeId setLumiBlock setRoiId setRoiSubsystem setRoiNumber roiEta
Definition: L2StandAloneMuon_v2.cxx:343
L1DataConsistencyChecker.h
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:12
TrigConf::L1Threshold::type
const std::string & type() const
Accessor to the threshold type.
Definition: L1ThresholdBase.h:157
TrigConf::DataStructure::name
virtual const std::string & name() const final
Definition: DataStructure.cxx:109
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
L1DataConsistencyChecker::m_thresholdTypes
std::unordered_map< TrigCompositeUtils::DecisionID, std::string > m_thresholdTypes
Definition: L1DataConsistencyChecker.h:64
L1DataConsistencyChecker::m_l1MenuKey
SG::ReadHandleKey< TrigConf::L1Menu > m_l1MenuKey
Definition: L1DataConsistencyChecker.h:39
xAOD::roiWord
roiWord
Definition: TrigMissingET_v1.cxx:36
HLT::IDVec
std::vector< HLT::Identifier > IDVec
Definition: TrigCompositeUtils/TrigCompositeUtils/HLTIdentifier.h:62
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
L1DataConsistencyChecker::m_errorOnMissingTOB
Gaudi::Property< bool > m_errorOnMissingTOB
Definition: L1DataConsistencyChecker.h:45
L1DataConsistencyChecker::m_thresholdMap
std::unordered_map< TrigCompositeUtils::DecisionID, MultiplicityInfo > m_thresholdMap
Definition: L1DataConsistencyChecker.h:62
L1DataConsistencyChecker::m_thresholdToDecisionMap
Gaudi::Property< std::map< std::string, std::string > > m_thresholdToDecisionMap
Definition: L1DataConsistencyChecker.h:48
Atlas::ExtendedEventContext
Definition: ExtendedEventContext.h:23
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
calibdata.exception
exception
Definition: calibdata.py:496
TrigConf::L1Item
L1 threshold configuration.
Definition: L1Item.h:18
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
L1DataConsistencyChecker::MultiplicityInfo
std::unordered_map< TrigCompositeUtils::DecisionID, unsigned int > MultiplicityInfo
Definition: L1DataConsistencyChecker.h:61
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
xAOD::TrigComposite_v1
Class used to describe composite objects in the HLT.
Definition: TrigComposite_v1.h:52
HLT::Identifier
Definition: TrigCompositeUtils/TrigCompositeUtils/HLTIdentifier.h:20
Monitored.h
Header file to be included by clients of the Monitored infrastructure.
xAOD::decisions
decisions
Definition: TrigComposite_v1.cxx:81
HLTSeedingRoIToolDefs::roiFromLink
std::optional< AnyRoIPointer > roiFromLink(const xAOD::TrigComposite &tc, const std::string &linkName)
Recursively try each type from AnyRoIPointer variant to retrieve an object from a TrigComposite link.
Definition: HLTSeedingRoIToolDefs.h:154
L1DataConsistencyChecker::initialize
virtual StatusCode initialize() override
Definition: L1DataConsistencyChecker.cxx:26
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
L1DataConsistencyChecker::doDebug
bool doDebug() const
Shorter alias for a check whether we are in DEBUG logging mode.
Definition: L1DataConsistencyChecker.h:68
item
Definition: ItemListSvc.h:43
HLTSeedingRoIToolDefs.h
L1DataConsistencyChecker::consistencyCheck
StatusCode consistencyCheck(const HLT::IDVec &l1SeededChains, const EventContext &ctx) const
Perform the check and fill the corresponding histograms.
Definition: L1DataConsistencyChecker.cxx:84
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
LogicParser.h
L1DataConsistencyChecker::m_excludedThresholdTypes
Gaudi::Property< std::vector< std::string > > m_excludedThresholdTypes
Definition: L1DataConsistencyChecker.h:51
HLTSeedingRoIToolDefs::roiTobEt
constexpr unsigned int roiTobEt(const AnyRoIPointer &roi)
Definition: HLTSeedingRoIToolDefs.h:206
str
Definition: BTagTrackIpAccessor.cxx:11
L1DataConsistencyChecker::m_monitoredThresholds
std::set< TrigCompositeUtils::DecisionID > m_monitoredThresholds
Definition: L1DataConsistencyChecker.h:65
Monitored::Scalar
Declare a monitored scalar variable.
Definition: MonitoredScalar.h:34
TrigConf::Chain
HLT chain configuration.
Definition: TrigConfData/TrigConfData/HLTChain.h:18
HLTSeedingRoIToolDefs
Definition: HLTSeedingRoIToolDefs.cxx:7
Monitored::Timer
A monitored timer.
Definition: MonitoredTimer.h:32
TrigConf::L1Threshold
Standard L1 threshold configuration.
Definition: L1ThresholdBase.h:125